在 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) 中的错误:无效的“类型”(字符) 论据

现在,v1v2 都作为字符变量从其他程序传递,所以我不能这样做 v1&lt;- 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 的编辑: paste0eval \ 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")) 快得多。至少,这是应该发生的,如果没有,那么它可能是一个错误。另一方面,如果许多查询是动态构建并重复的,那么paste0parse 的时间可能会出现。一切都取决于。设置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 中创建虚拟变量

R data.table:如何使用包含列名的 R 变量?

R 中 data.table 的 colnames() 行为

在 R 中,自定义由 dcast.data.table 创建的列的名称

匹配一个变量后,仅将一个变量从一个 R data.table 复制到另一个

使用 data.table 包滚动平均值到 R 中的多个变量