data.table by with substitute,eval和deparse

时间:2013-11-21 12:36:11

标签: r data.table

问题1:为何不一致?

dt <- data.table(x=1:4, y=c(1,1,2,2), z=c(1,2,1,2))

test1 <- function(dt, a){
    t <- deparse(substitute(a))
    dt[,list(x=sum(x)), by=t]

}
test1(dt, y) # Works well
   y x
1: 1 3
2: 2 7

test2 <- function(dt, a){
    dt[,list(x=sum(x)), by=deparse(substitute(a))]
}
test2(dt, y)
# Error: 'by' appears to evaluate to column names but isn't c() or key().

问题2:

似乎我可以在两个帧中执行以下操作?这是为什么?我应该使用哪一个?

test1 <- function(dt, a){
    dt[,list(x=sum(x)), by=eval(substitute(a))]

}
test1(dt, y)
   substitute x
1:          1 3
2:          2 7
> 
test2 <- function(dt, a){
    dt[,list(x=sum(x)), by=eval(substitute(a), parent.frame())]    
}
test2(dt, y)
   substitute x
1:          1 3
2:          2 7

1 个答案:

答案 0 :(得分:2)

您没有重现完整错误:

  

test2(dt,y)   [.data.table中的错误(dt ,, list(x = sum(x)),by = deparse(substitute(a))):     &#39;由&#39;似乎评估列名但不是c()或key()。如果可以,请使用= list(...)。否则,通过= eval(deparse(substitute(a)))应该有效。这是为了提高效率,因此data.table可以检测到需要哪些列。

正如所建议的那样(或者仅仅是暗示过),你可以通过封闭在c

来获得成功
 test2 <- function(dt, a){
     dt[,list(x=sum(x)), by=c(deparse(substitute(a)))]
     }

> test2(dt, y)
   y x
1: 1 3
2: 2 7

我认为c()会强制进行评估。