web-dev-qa-db-fra.com

dplyr: lead () et lag () incorrects lorsqu'ils sont utilisés avec group_by ()

Je veux trouver l'élément lead () et lag () dans chaque groupe, mais j'ai obtenu des résultats erronés.

Par exemple, les données sont comme ceci:

library(dplyr)
df = data.frame(name=rep(c('Al','Jen'),3),
                score=rep(c(100, 80, 60),2))
df

Les données:

  name score
1   Al   100
2  Jen    80
3   Al    60
4  Jen   100
5   Al    80
6  Jen    60

Maintenant, j'essaie de trouver les scores lead () et lag () pour chaque personne. Si je le trie en utilisant arrange (), je peux obtenir la bonne réponse:

df %>%
  arrange(name) %>%
  group_by(name) %>%
  mutate(next.score = lead(score),
         before.score = lag(score) )

SORTIE 1:

Source: local data frame [6 x 4]
Groups: name

      name score next.score before.score
    1   Al   100         60           NA
    2   Al    60         80          100
    3   Al    80         NA           60
    4  Jen    80        100           NA
    5  Jen   100         60           80
    6  Jen    60         NA          100

Sans arrange (), le résultat est faux:

df %>%
  group_by(name) %>%
  mutate(next.score = lead(score),
         before.score = lag(score) )

SORTIE2:

Source: local data frame [6 x 4]
Groups: name

  name score next.score before.score
1   Al   100         80           NA
2  Jen    80         60           NA
3   Al    60        100           80
4  Jen   100         80           60
5   Al    80         NA          100
6  Jen    60         NA           80

Par exemple, en 1ère ligne, le prochain score d'Al devrait être de 60 (3ème ligne).

Quelqu'un sait pourquoi cela s'est produit? Pourquoi arrange () affecte le résultat (les valeurs, pas seulement l'ordre)? Merci ~

31
YJZ

Il semble que vous deviez passer un argument supplémentaire pour retarder et diriger les fonctions. Lorsque j'exécute votre fonction sans organiser, mais avec order_by ajouté, tout semble aller bien.

df %>%
group_by(name) %>%
mutate(next.score = lead(score, order_by=name),
before.score = lag(score, order_by=name))

Sortie:

  name score next.score before.score
1   Al   100         60           NA
2  Jen    80        100           NA
3   Al    60         80          100
4  Jen   100         60           80
5   Al    80         NA           60
6  Jen    60         NA          100

Ma sessionInfo ():

R version 3.1.1 (2014-07-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)

locale:
[1] LC_COLLATE=Polish_Poland.1250  LC_CTYPE=Polish_Poland.1250        LC_MONETARY=Polish_Poland.1250
[4] LC_NUMERIC=C                   LC_TIME=Polish_Poland.1250    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] dplyr_0.4.1

loaded via a namespace (and not attached):
[1] assertthat_0.1  DBI_0.3.1       lazyeval_0.1.10 magrittr_1.5                parallel_3.1.1  Rcpp_0.11.5    
[7] tools_3.1.1 
34
Tomasz Sosiński

L'utilisation de order_by est bonne lorsque vous n'avez qu'une seule variable de regroupement. En cas de variable de regroupement multiple, je n'ai pu trouver de solution que d'écrire et de lire le tableau pour se débarrasser des variables de regroupement. Cela a plutôt bien fonctionné pour moi, mais son efficacité dépend de la taille de la table.

2
Adrian

Il peut arriver que stats::lag est utilisé à la place (par exemple lors de la restauration d'environnements avec le package session). Cela peut facilement passer inaperçu car il ne générera pas d'erreur lorsqu'il sera utilisé comme dans la question. Revérifiez en tapant simplement lag, utilisez le package conflicted ou supprimez l'ambiguïté de l'appel de fonction en appelant dplyr::lag au lieu.

1
Holger Brandl