弗洛德尔在评论中的答案的替代方案可能是
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
and eval
\quote
方法也比get
某些情况下更快。分组速度很快的原因之一是data.table
检查j
它使用了哪些列,然后只对那些使用的列进行子集化(FAQ 1.12 和 3.1)。它用来base::all.vars(j)
做到这一点。在使用get()
的j
列中使用时,会隐藏all.vars
并data.table
回退到对所有列进行子集化,以防j
表达式需要它们(很像在 中.SD
使用符号时j
,.SDcols
添加用于求解)。如果无论如何都使用了所有列,那么它没有任何区别,但是如果DT
说 1e7x100 那么分组j=sum(V1)
j=sum(get("V1"))
由于这个原因,应该比分组快得多。至少,这是应该发生的,如果没有,那么它可能是一个错误。另一方面,如果许多查询是动态构建并重复的,那么时间paste0
可能parse
会进入它。一切都取决于。设置verbose=TRUE
应该打印出一条消息,说明哪些列已被 检测到j
,以便可以检查。