Rdata.table.SD意外行为

我试图计算数据表的一些基本统计数据,但我遇到了这种(对我而言)意外的行为。如果我使用“显式”索引使用所有内容进行计算,则一切都按预期工作,如下例所示:

library(data.table)
n <- 100; reps <- 6; n1 <- 2
df <-  as.data.frame(cbind(matrix(seq_len(n*n1), ncol=n1),
      matrix(sample(0:1000, n*reps, replace=TRUE), ncol=reps)))
dt <- data.table(df)

dtmean <- dt[, lapply(.SD[,c(seq(2,5))], mean, na.rm=TRUE), by=c("V1")]

但如果我使用

a=2
b=5

dtmean <- dt[, lapply(.SD[,c(seq(a,b))], mean, na.rm=TRUE), by=c("V1")]

结果不是我所期望的(前几行)

这是故意的 data.table 应该如何工作吗?

所以 n=10 的第一部分代码给出

   V1  V3  V4  V5  V6
 1:  1 504 399 430 564
 2:  2 547 294 274 700
 3:  3 555 305 781 326
 4:  4 144 840 983 221
 5:  5 894 659 169  38
 6:  6 788 289 598 433
 7:  7 810 378  86  22
 8:  8 848 212 701 565
 9:  9 412 707 890 160
10: 10  82 580 927 607

而第二

    V1 V1 V2 V3 V4
 1:  1  2  3  4  5
 2:  2  2  3  4  5
 3:  3  2  3  4  5
 4:  4  2  3  4  5
 5:  5  2  3  4  5
 6:  6  2  3  4  5
 7:  7  2  3  4  5
 8:  8  2  3  4  5
 9:  9  2  3  4  5
10: 10  2  3  4  5

他们不应该给我同样的结果吗?这里的函数 mean 不计算任何东西,因为 V1 有所有不同的值,问题是关于索引的选择,我不明白为什么它们以不同的方式工作。

回答

您应该使用.SDcols来控制.SD在这种情况下包含的内容:

dtmean <- dt[, lapply(.SD, mean, na.rm=TRUE), by="V1", .SDcols=seq(a,b)]

要做到你的风格,你应该with=FALSE在内部.SD调用中使用:

dtmean <- dt[, lapply(.SD[, seq(a,b), with=FALSE], mean, na.rm=TRUE), by=c("V1")]

.SD本身是 a data.table,因此[具有相同的语义,即问题与之间的差异相同

dt[ , seq(a,b)]

dt[ , seq(a,b), with=FALSE]

附录需要注意的是.SDcols,也可以用来确定ab内嵌在某些情况下,例如,如果a:b仅仅是表的数值列,我们可以使用:

dt[ , lapply(.SD, mean, na.rm=TRUE), by=V1, .SDcols=is.numeric]

或者,如果a:b他们的名字中有一个模式,例如:

dt[ , lapply(.SD, mean, na.rm=TRUE), by=V1, .SDcols=patterns("ends_with_x$")]


以上是Rdata.table.SD意外行为的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>