每组最后一行的data.table计算

时间:2019-08-20 12:38:57

标签: r data.table

当我将data.table分组时

library(data.table)
dat <- data.table(id=1:10, group=rep(1:2, each=5), x=rnorm(10))

> dat
    id group           x
 1:  1     1 -0.39384959
 2:  2     1 -0.03081369
 3:  3     1 -1.30571673
 4:  4     1 -1.82379155
 5:  5     1  2.36751011
 6:  6     2  0.21523454
 7:  7     2 -0.18905780
 8:  8     2  1.80707868
 9:  9     2  0.88348164
10: 10     2  0.38374826

,并且我想将每个组中的最后一个x的{​​{1}}设置为零,我想知道如何实现。我的想法是id,但是这样做不起作用,因为这只会更改id 10的值。为什么?小插图似乎对这里没有帮助。

3 个答案:

答案 0 :(得分:2)

这里有些原始:

dat[, x := ifelse(seq_along(x) == .N, 0, x), group][]

更简洁:

dat[, x := c(x[-.N], 0), group]

可能更有效的是:

dat[dat[, .I[.N], group]$V1, x := 0]

答案 1 :(得分:1)

可以使用:

dat[,x:= ifelse(.I == last(.I),0,x),by=.(group)][]



     id group          x
 1:  1     1 -0.6291830
 2:  2     1 -0.1840518
 3:  3     1  0.5242331
 4:  4     1 -1.8604996
 5:  5     1  0.0000000
 6:  6     2 -1.3966630
 7:  7     2  0.8715680
 8:  8     2 -0.6207351
 9:  9     2 -0.3021389
10: 10     2  0.0000000

答案 2 :(得分:0)

也许您可以使用replace

library(data.table)
dat[, x := replace(x, seq_len(.N) == .N, 0),by=group]

dat
#    id group          x
# 1:  1     1 -0.3148360
# 2:  2     1 -0.1737918
# 3:  3     1 -0.6768283
# 4:  4     1  0.4066397
# 5:  5     1  0.0000000
# 6:  6     2 -0.3606155
# 7:  7     2  0.1965135
# 8:  8     2  0.1488247
# 9:  9     2 -1.8684589
#10: 10     2  0.0000000

@sindri_baldur建议的或更简单的方法

dat[, x := replace(x, .N, 0),by=group]