我遇到了一个 R 小问题data.table
。非常感谢您的帮助。我该怎么做呢:
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
and v2
从其他程序作为字符变量传递,所以我不能这样做v1<- quote(Sepal.Length)
这似乎有效。
弗洛德尔在评论中的回答的替代方案可能是
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
EDIT:
并将其放入一个函数中,
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
马修的编辑:有一个微妙的原因paste0
and eval
\ quote
方法可以比get
在某些情况下也是如此。分组速度快的原因之一是data.table
检查j
要查看它使用了哪些列,则仅对那些使用的列进行子集化(常见问题解答 1.12 和 3.1)。它用base::all.vars(j)
要做到这一点。使用时get()
in j
正在使用的列被隐藏all.vars
and data.table
回退到对所有列进行子集化,以防万一j
表达式需要它们(很像当.SD
符号用于j
,对于其中.SDcols
添加来解决)。如果无论如何都使用所有列,那么它没有什么区别,但是如果DT
就是说 1e7x100 然后分组j=sum(V1)
应该比分组快得多j=sum(get("V1"))
是因为。至少,这是应该发生的事情,如果没有发生,那么它可能是一个错误。另一方面,如果许多查询是动态构造并重复的,那么需要时间paste0
and parse
可能会涉及其中。一切都取决于实际情况。环境verbose=TRUE
应该打印出一条消息,说明哪些列已被检测到被使用j
,这样就可以检查了。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)