dplyr: lead() I lag() źle użyte z group by()

Chcę znaleźć element lead() I lag() w każdej grupie, ale miałem złe wyniki.

Na przykład dane są takie:

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

Data:

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

Teraz staram się znaleźć wyniki lead () I lag() dla każdej osoby. Jeśli posortuję go za pomocą arrange (), mogę uzyskać poprawną odpowiedź:

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

OUTPUT1:

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

Bez arrange () wynik jest błędny:

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

OUTPUT2:

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
Np. w pierwszej linii Al jest następny.wynik powinien wynosić 60 (3. linii). Ktoś wie, dlaczego to się stało? Dlaczego funkcja arrange() wpływa na wynik (wartości, a nie tylko kolejność)? Dzięki ~
 26
Author: hrbrmstr, 2015-01-30

2 answers

Wydaje się, że trzeba przekazać dodatkowy argument do funkcji lag i lead. Kiedy uruchamiam twoją funkcję bez aranżacji, ale z dodanym order_by, wszystko wydaje się być ok.

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

Wyjście:

  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

My 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 
 27
Author: Tomasz Sosiński,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-01 15:14:10

Użycie order_by jest dobre, gdy masz tylko jedną zmienną grupującą. W przypadku wielu zmiennych grupujących nie mogłem znaleźć żadnego rozwiązania poza zapisem i odczytaniem tabeli, aby pozbyć się zmiennych grupujących. Dla mnie to działało całkiem dobrze, ale jego wydajność zależy od wielkości tabeli.

 2
Author: Adrian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-06 20:01:14