问题描述
环形复杂性 衡量可以通过功能来衡量多少个可能的分支.是否有现有功能/工具来计算R函数?如果不是,则对最佳写作方式表示赞赏.
廉价的开始将是计算您功能中if,ifelse或switch的所有出现.但是,要获得一个真正的答案,您需要了解分支机构何时开始和结束,这要困难得多.也许某些R解析工具会让我们开始?
推荐答案
另外,我刚刚找到了一个名为CycloComp(2016年发布)的新软件包.检查一下!
其他推荐答案
您可以使用codetools::walkCode走代码树.不幸的是,CodeTools的文档非常稀疏.这是一个解释和样本,可以让您入门.
walkCode采用表达式和代码步行器.代码步行器是您创建的列表,必须包含三个回调函数:handler,call和leaf. (您可以使用助手函数makeCodeWalker提供每个的明智默认实现.)walkCode在代码树上行走并在代码沃克中拨打呼叫.
当遇到化合物表达式时,call(e, w)被调用. e是表达式,w是代码步行者本身.默认实现只是递归到表达的子节点(for (ee in as.list(e)) if (!missing(ee)) walkCode(ee, w))中.
当遇到树中的叶子节点时,leaf(e, w)被调用.同样,e是叶节点表达式,w是代码步行器.默认实现仅为print(e).
handler(v, w)针对每个化合物表达式调用,可用于轻松为某些类型的表达式提供call的替代行为. v是化合物表达式父母的字符串字符串表示(很难解释 - 但基本上是<-如果它是分配表达式,则{如果是块的开始,if如果是if statement等).如果处理程序返回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 }