【发布时间】:2021-02-03 14:57:28
【问题描述】:
我想写一个函数outer_fun(),它做一些事情,还调用另一个函数inner_fun()。来自outer_fun() 的所有参数都传递给inner_fun()。
inner_fun() 对 data.table 进行一些计算(这是两个函数的参数)。另一个要通过函数传递的参数是by。
这是我所拥有的草图:
library(data.table)
data("CO2")
setDT(CO2)
outer_fun <- function(DT, by) {
# some other stuff
by <- substitute(by)
inner_fun(DT, by)
}
inner_fun <- function(DT, by) {
DT[, .(mean = mean(uptake)),
by = list(Plant, by)]
}
outer_fun(CO2, by = Type)
这会引发错误:
Error in `[.data.table`(DT, , .(mean = mean(uptake)), by = list(Plant, :
column or expression 2 of 'by' or 'keyby' is type language. Do not quote column names. Usage: DT[,sum(colC),by=list(colA,month(colB))]
据我了解这个问题,我必须将by 中的两个列表正确组合到inner_fun() 中。另一种尝试是这样的:
outer_fun <- function(DT, by) {
# some other stuff
by <- substitute(by)
inner_fun(DT, by)
}
inner_fun <- function(DT, by) {
.by <- append(by, substitute(Plant), after = 0L)
DT[, .(mean = mean(uptake)),
by = eval(as.expression(list(.by)))]
}
outer_fun(CO2, by = Type)
这会引发类似的错误:
Error in `[.data.table`(DT, , .(mean = mean(uptake)), by = eval(as.expression(list(.by)))) :
column or expression 1 of 'by' or 'keyby' is type symbol. Do not quote column names. Usage: DT[,sum(colC),by=list(colA,month(colB))]
我在这里挣扎了两天,非常感谢您的帮助!
编辑:
看来,我还不清楚所需的解决方案应该具备什么能力。结果应该适用于data.table中允许的各种by,例如:
outer_fun(CO2, by = Type)
outer_fun(CO2, by = "Type")
outer_fun(CO2, by = .(Type, Treatment))
outer_fun(CO2, by = c("Type", "Treatment"))
outer_fun(CO2, by = "Type,Treatment")
outer_fun(CO2, by = Treatment == "chilled")
outer_fun(CO2, by = cut(conc, breaks = quantile(conc)))
...
【问题讨论】:
-
您不想使用像
"Type"这样的字符串吗?对于by中的两列或更多列,您希望使用哪种语法? -
好吧,两者都是(字符串和表达式)。我想保留在 data.table 中工作的所有内容。所以对于两列,c("col1", "col2"), "col1,col2", .(col1, col2)。
-
我应该补充一点,我需要保持对 col1 > 5 等表达式的支持。
-
我认为@jangorecki 有一个处理此类用例的 PR
标签: r data.table evaluation