R语言data.table函数嵌套调用时无法识别已定义参数求助
解决data.table::dcast在函数内调用时找不到fun参数的问题
这个坑我之前踩过!你遇到的问题本质是data.table和reshape2的dcast在函数环境下的参数解析逻辑完全不同,咱们先把你的示例补全成可复现的代码,再一步步解决:
# 补全你的testFun1定义 testFun1 <- function(data, formula, fun = sum, value.var = "value") { data.table::dcast(data = data, formula = formula, fun.aggregate = fun, value.var = value.var) } # 正常工作的testFun2 testFun2 <- function(data, formula, fun = sum, value.var = "value") { reshape2::dcast(data = data, formula = formula, fun.aggregate = fun, value.var = value.var) } # 测试用数据 dt <- data.table::data.table( id = rep(1:3, each = 2), category = c("A", "B", "A", "B", "A", "B"), value = 1:6 ) # 调用testFun1会报错:could not find function "fun" testFun1(dt, id ~ category) # testFun2则正常输出结果 testFun2(dt, id ~ category)
为什么会出现这个错误?
data.table的dcast在处理fun.aggregate参数时,会默认去全局环境里查找对应的函数名称,而不是在当前的函数局部环境里找。当你把fun作为函数参数传入testFun1时,它只存在于testFun1的局部环境中,data.table的dcast找不到它,就抛出了找不到函数的错误。
而reshape2的dcast是直接在当前调用环境(也就是testFun2的局部环境)里解析参数,所以能正常识别fun对应的函数。
几种可行的修复方案
方案1:用match.fun()显式获取函数对象
match.fun()会在当前环境中查找对应的函数并返回函数对象,直接传递给dcast就不会有查找问题:
testFun1_fix1 <- function(data, formula, fun = sum, value.var = "value") { data.table::dcast(data = data, formula = formula, fun.aggregate = match.fun(fun), value.var = value.var) } # 测试修复后的函数 testFun1_fix1(dt, id ~ category) # id A B # 1: 1 1 2 # 2: 2 3 4 # 3: 3 5 6
方案2:将函数名转为字符串,用get()从父环境获取
如果习惯用字符串传递函数名,也可以这样写:
testFun1_fix2 <- function(data, formula, fun = "sum", value.var = "value") { data.table::dcast(data = data, formula = formula, fun.aggregate = get(fun, envir = parent.frame()), value.var = value.var) } testFun1_fix2(dt, id ~ category)
这里parent.frame()指定从testFun1的环境中获取函数,避免去全局环境查找。
方案3:用eval()强制在当前环境解析
这种方式稍显繁琐,但也能解决问题:
testFun1_fix3 <- function(data, formula, fun = sum, value.var = "value") { eval(quote(data.table::dcast(data = data, formula = formula, fun.aggregate = fun, value.var = value.var)), envir = environment()) }
总结
两个包的dcast设计逻辑不同,data.table的dcast为了性能优化,对函数参数的查找规则更严格。在函数内部调用时,只要显式地把函数对象传递给fun.aggregate,就能避开这个坑啦。
内容的提问来源于stack exchange,提问作者Jiexing Wu
相关产品推荐
相关产品推荐

