Cyclomatic complexity测量可以通过函数获取多少个可能的分支。是否有现有的函数/工具来计算R函数?如果没有,建议是最好的方式来写一个。
一个便宜的开始就是计算你职能中if
,ifelse
或switch
的所有出现次数。要获得真正的答案,您需要了解分支何时开始和结束,这要困难得多。也许一些R解析工具会让我们开始?
答案 0 :(得分:7)
您可以使用codetools::walkCode
遍历代码树。不幸的是,codetools的文档非常稀少。这是一个解释和示例,以帮助您入门。
walkCode
采用表达式和代码walker。代码walker是您创建的列表,必须包含三个回调函数:handler
,call
和leaf
。 (您可以使用辅助函数makeCodeWalker
为每个函数提供合理的默认实现。)walkCode
遍历代码树并调用代码遍历器。
call(e, w)
。 e
是表达式,w
是代码walker本身。默认实现只是简单地递归到表达式的子节点(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
}
答案 1 :(得分:2)
另外,我刚刚发现了一个名为cyclocomp的新软件包(2016年发布)。看看吧!