如何使用data.table

时间:2015-11-05 22:45:51

标签: r data.table

在评估包含列表和原子类型的data.table表达式时j遇到困难

请看以下示例:

library(data.table)
set.seed(1)
N=1e5
DT = data.table(x=sample(1:5,N,replace=T),
                y=sample(letters[1:5],N,replace=T),
                v=rnorm(N))
DT[,c(nbPoints=.N,as.list(quantile(v,probs = seq(0,1,.25)))),.(x,y)]

我可以命名nbPoints而不是quintiles(q%是默认命名)。 我可以将分位数WITHIN重命名为j表达式吗?

    x y nbPoints        0%        25%           50%       75%     100%
 1: 2 d     4035 -4.218131 -0.6544560  0.0162812744 0.6851001 3.361237
 2: 3 b     3890 -3.619431 -0.6493404 -0.0030014514 0.6930898 3.566787
 3: 5 c     4055 -3.593988 -0.6718406 -0.0143884613 0.6464294 3.329382

我会喜欢这样的东西: DT[,c(nbPoints=.N,paste0('c',1:5)=as.list(quantile(v,probs = seq(0,1,.25)))),.(x,y)]

获取

    x  y nbPoints        p1        p2           p3       p4     p5
 1: 2 d     4035 -4.218131 -0.6544560  0.0162812744 0.6851001 3.361237
 2: 3 b     3890 -3.619431 -0.6493404 -0.0030014514 0.6930898 3.566787
 3: 5 c     4055 -3.593988 -0.6718406 -0.0143884613 0.6464294 3.329382

但那不起作用

1 个答案:

答案 0 :(得分:4)

使用by创建新列时,遵循语法DT[i, j, by]j应评估为列列表。他们的名字来自j或自动分配,没有找到名字。

要为列表指定名称,可以使用setNames。在OP的例子中:

DT[, c(
  nbPoints=.N,  
  setNames(
    as.list(quantile(v,probs = seq(0,1,.25))),
    LETTERS[1:5]
  )
), by=.(x,y)]

正如@thelatemail建议的那样,您可以改为立即命名整个矢量:

DT[, setNames( 
  c(list(.N), quantile(v,probs = seq(0,1,.25))), 
  c("nbPoints", LETTERS[1:5]) 
), by=.(x,y)]

LETTERS[1:5]可以替换为其他所需的名称。还可以使用更快捷的方式来分配名称,例如setattr(L, "names", LETTERS[1:5]),这将避免复制列表。

评论。构建列表时,it is best to avoid coercing to one with as.list。不过,我在这里看不到好的方法。