You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于R data.table cube()函数作用域的困惑及传参问题

data.table::cube() 作用域问题与函数传递解决方案

问题原因

data.table的cube()、rollup()、groupingsets()这类函数在解析j参数中的表达式时,默认会在目标数据对象的内部环境中查找符号,而非调用cube()的函数环境。

第一个示例能运行,是因为summary_fn定义在全局环境中,而全局环境是数据对象环境的父环境,因此可以被找到;但第二个示例中,summary_fn是cube_fn的局部参数,仅存在于cube_fn的函数环境中,数据对象的环境无法访问这个局部作用域,所以会抛出could not find function "summary_fn"的错误。

正确传递函数的方法

方法1:使用get()指定环境获取函数

通过get()从cube_fn的父环境(即函数本身的环境)中提取summary_fn:

cube_fn = function(summary_fn) {
  cubed <- data.table::cube(
    flights,
    .(distance = get("summary_fn", parent.frame())(distance)),
    by = c("month", "origin")
  )
}

print(cube_fn(mean))

方法2:结合eval()与quote()控制表达式求值环境

先将j表达式用quote()包裹,再通过eval()指定在cube_fn的环境中求值:

cube_fn = function(summary_fn) {
  j_expr <- quote(.(distance = summary_fn(distance)))
  cubed <- data.table::cube(
    flights,
    eval(j_expr, envir = environment()),
    by = c("month", "origin")
  )
}

print(cube_fn(mean))

方法3:使用rlang的非标准求值(!!)

借助rlang包的!!操作符,将局部函数参数直接注入表达式中:

library(rlang)
cube_fn = function(summary_fn) {
  cubed <- data.table::cube(
    flights,
    .(distance = !!summary_fn(distance)),
    by = c("month", "origin")
  )
}

print(cube_fn(mean))

内容的提问来源于stack exchange,提问作者Matt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 04:06:09