我试图计算数据表的一些基本统计数据,但我发现了这种(对我来说(意外的行为。如果我使用";明确的";索引一切工作如预期,如下例所示:
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)]
要按照自己的风格进行操作,您应该在内部.SD
调用中使用with=FALSE
:
dtmean <- dt[, lapply(.SD[, seq(a,b), with=FALSE], mean, na.rm=TRUE), by=c("V1")]
.SD
本身就是data.table
,因此[
具有相同的语义,即问题与之间的差异相同
dt[ , seq(a,b)]
和
dt[ , seq(a,b), with=FALSE]
注意,在某些情况下,.SDcols
也可用于确定a
、b
内联,例如,如果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$")]