1
votes

calcul data.table pour la dernière ligne par groupe

Lorsque j'ai une table de données groupée

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

et que je souhaite mettre x à zéro pour le dernier id dans chaque groupe, je me demande comment cela peut être réalisé. Ma prise était dat [.N, x: = 0, by = group] mais cela ne fonctionnerait pas car cela ne change que la valeur de l'id 10. Pourquoi est-ce? La vignette ne semble pas aider ici.


0 commentaires

3 Réponses :


0
votes

Vous pourriez peut-être utiliser replace

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

Ou une approche plus simple suggérée par @sindri_baldur

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


1 commentaires

Peut simplifier pour remplacer (x, .N, 0) .



2
votes

Voici quelque chose d'un peu primitif:

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

Plus concis:

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

Probablement plus efficace est:

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


0 commentaires

1
votes

Peut utiliser:

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


0 commentaires