在 R data.table 中,如何将变量参数传递给表达式?
Posted
技术标签:
【中文标题】在 R data.table 中,如何将变量参数传递给表达式?【英文标题】:In R data.table, how do I pass variable parameters to an expression? 【发布时间】:2012-05-27 08:37:16 【问题描述】:我遇到了data.table
的一个小 R 问题。非常感谢您的帮助。我该怎么做:
getResult <- function(dt, expr, gby)
e <- substitute(expr)
b <- substitute(gby)
return(dt[,eval(e),by=b])
v1 <- "Sepal.Length"
v2 <- "Species"
dt <- data.table(iris)
rDT <- getResult(dt, sum(v1, na.rm=TRUE), v2)
我收到以下错误:
sum(v1, na.rm = TRUE) 中的错误:无效的“类型”(字符) 论据
现在,v1
和 v2
都作为字符变量从其他程序传递,所以我不能这样做 v1<- quote(Sepal.Length)
这似乎有效。
【问题讨论】:
这可能会让你走上正轨:dt[, sum(get(v1), na.rm=TRUE), by=v2]
或者如果你灵活的话,可以建议一种替代方法。
谢谢。它起作用了,发生了什么?函数获取名为 v1 的对象。替换函数对这个表达式做了什么?它没有做任何事情并试图用字符值“Sepal.Length”替换v1吗?
【参考方案1】:
flodel 在 cmets 中的答案的替代方案可能是
e <- parse(text = paste0("sum(", v1, ", na.rm = TRUE)"))
b <- parse(text = v2)
rDT2 <- dt[, eval(e), by = eval(b)]
# b V1
# [1,] setosa 250.3
# [2,] versicolor 296.8
# [3,] virginica 329.4
编辑:
并将其放入函数中,
getResult <- function(dt, expr, gby)
return(dt[, eval(expr), by = eval(gby)])
(dtR <- getResult(dt = dt, expr = e, gby = b))
# gives the same result as above
来自 Matthew 的编辑:
paste0
和 eval
\ quote
方法在某些情况下也比 get
更快,这是有一个微妙的原因。分组速度很快的原因之一是data.table
检查j
以查看它使用了哪些列,然后仅对那些使用的列进行子集化(FAQ 1.12 和 3.1)。它使用base::all.vars(j)
来做到这一点。当在j
中使用get()
时,正在使用的列对all.vars
隐藏,data.table
回退到子集所有列以防j
表达式需要它们(就像.SD
符号是用于j
,为此添加.SDcols
解决)。如果无论如何都使用了所有列,那么它没有任何区别,但是如果 DT
是 1e7x100,那么分组 j=sum(V1)
应该比分组 j=sum(get("V1"))
快得多。至少,这是应该发生的,如果没有,那么它可能是一个错误。另一方面,如果许多查询是动态构建并重复的,那么paste0
和parse
的时间可能会出现。一切都取决于。设置verbose=TRUE
应该会打印出一条消息,说明已检测到哪些列被j
使用,以便可以检查。
【讨论】:
谢谢,回到原来的问题,我该如何使用你的解决方案 getResult @user1157129,很抱歉遗漏了您问题中要求的功能。请参阅编辑以获取建议。 抱歉,Ben,它不工作,我在搞砸什么吗? getResult @user1157129,我在使用 R 2.13.1 补丁和 data.table 1.7.10 时遇到此错误 - 你能升级到这两个包的最新版本吗? 是的,升级到 R 2.15 和 data.table 1.8 解决了这个问题。感谢本的帮助!以上是关于在 R data.table 中,如何将变量参数传递给表达式?的主要内容,如果未能解决你的问题,请参考以下文章
R 中 data.table 的 colnames() 行为
在 R 中,自定义由 dcast.data.table 创建的列的名称