将边际总和添加到数据表的正确方法是什么?
我现在做的是什么:
> (a <- data.table(x=c(1,2,1,2,2,3,3),y=c(10,10,20,20,30,30,40),z=1:7,key=c("x")))
x y z
1: 1 10 1
2: 1 20 3
3: 2 10 2
4: 2 20 4
5: 2 30 5
6: 3 30 6
7: 3 40 7
> (a <- a[a[,sum(z),by=x]])
x y z V1
1: 1 10 1 4
2: 1 20 3 4
3: 2 10 2 11
4: 2 20 4 11
5: 2 30 5 11
6: 3 30 6 13
7: 3 40 7 13
> setnames(a,"V1","x.z")
> setkeyv(a,"y")
> (a <- a[a[,sum(z),by=y]])
y x z x.z V1
1: 10 1 1 4 3
2: 10 2 2 11 3
3: 20 1 3 4 7
4: 20 2 4 11 7
5: 30 2 5 11 11
6: 30 3 6 13 11
7: 40 3 7 13 7
> setnames(a,"V1","y.z")
我很确定这不是正确的方法。
什么是?
答案 0 :(得分:10)
另一种选择是:
> a[,Sum:=sum(z), by="x"]
> a
x y z Sum
1: 1 10 1 4
2: 1 20 3 4
3: 2 10 2 11
4: 2 20 4 11
5: 2 30 5 11
6: 3 30 6 13
7: 3 40 7 13
:=
用法的更多解释: :=
运算符通过引用启用添加/更新。有了这个,你可以:
通过引用添加新列或更新现有列
DT[, x2 := x+1] # add one new column
DT[, `:=`(x2 = x+1, y2 = y+1)] # adding more than 1 col
DT[, x := x+1] # modify existing column
添加或更新 某些行新列或现有列
DT[x == 1L, y := NA] # modify 'y' just where expression in 'i' matches
DT[x == 1L, `:=`(y = NA, z=NA)] # same but for multiple columns
DT[x == 1L, newcol := 5L] # matched rows for 'newcol' will be 5, all other 'NA'
添加或更新 cols,而分组,通过引用 - 默认情况下,计算结果会在每个组中循环使用。< / p>
DT[, zsum := sum(z), by=x]
此处,
sum(z)
为x
中的每个组返回1个值。然后将结果回收 组的长度,并通过引用zsum
添加/更新。
在 by-without-by 操作期间添加或更新。也就是说,当您执行data.table
加入并且想要在加入时添加/更新列时:
X <- data.table(x=rep(1:3, each=2), y=1:6, key="x")
Y <- data.table(x=1:3, y=c(3L, 1L, 2L), key="x")
X[Y, y.gt := y > i.y]
最后,您还可以通过引用删除列(即使即使它是20GB的表格):
DT[, x := NULL] # just 1 column
DT[, c("x","y") := NULL] # 1 or more columns
toRemove = c("x","y")
DT[, (toRemove) := NULL] # wrap with brackets to lookup variable
希望这有助于澄清:=
上的用法。另请查看?set
。它与:=
类似,但有无法与连接组合的限制。这允许它在for
循环内更快(由于减少了不调用[.data.table
的开销),因为它能够执行:=
以外的所有操作。
它可以非常方便,特别是在某些情况下。请参阅this post以获得更好的用法。