Ric*_*ton 15 complexity-theory r cyclomatic-complexity
Cyclomatic复杂度测量可以通过函数获取多少个可能的分支.是否有现有的函数/工具来计算R函数?如果没有,建议是最好的方式来写一个.
朝着这个一个廉价的启动将是计数的所有出现次数if,ifelse或者switch你的函数中.要获得真正的答案,您需要了解分支何时开始和结束,这要困难得多.也许一些R解析工具会让我们开始?
您可以使用它codetools::walkCode来遍历代码树.不幸的是,codetools的文档非常稀少.这是一个解释和示例,以帮助您入门.
walkCode采用表达式和代码walker.A码沃克是您创建一个列表,必须包含三个回调函数:handler,call,和leaf.(您可以使用辅助函数makeCodeWalker为每个函数提供合理的默认实现.)walkCode遍历代码树并调用代码walker.
call(e, w)在遇到复合表达式时调用.e是表达式,w是代码行者本身.默认实现只是简单地递归到表达式的子节点(for (ee in as.list(e)) if (!missing(ee)) walkCode(ee, w))中.
leaf(e, w)在遇到树中的叶节点时调用.同样,e是叶节点表达式并且w是代码walker.默认实现很简单print(e).
handler(v, w)为每个复合表达式调用,可用于call为某些类型的表达式轻松提供替代行为.v是复合表达式的父级的字符串表示(有点难以解释 - 但基本上<-如果它是赋值表达式,{如果它是块的开头,if如果它是if语句,等等).如果处理程序返回,NULL则call照常调用; 如果你返回一个函数,那就是调用而不是函数.
下面是计算的出现一个非常简单的例子if和ifelse功能的.希望这至少可以让你开始!
library(codetools)
countBranches <- function(func) {
count <- 0
walkCode(body(func),
makeCodeWalker(
handler=function(v, w) {
if (v == 'if' || v == 'ifelse')
count <<- count + 1
NULL # allow normal recursion
},
leaf=function(e, w) NULL))
count
}
Run Code Online (Sandbox Code Playgroud)