2017-11-23 4 views
3

Ich habe einige Daten mit Gruppen, für die ich eine Zusammenfassung (Summe oder Mittelwert) über eine feste Anzahl von Perioden berechnen möchte. Ich versuche, dies mit einer group_by zu tun, gefolgt von mutieren und dann mit der Variable arbeiten und es ist dplyr :: lag. Hier ein Beispiel:r Gruppe Lag Summe

library(tidyverse) 
df <- data.frame(group = rep(c("A", "B"), 5), 
        x = c(1, 3, 4, 7, 9, 10, 17, 29, 30, 55)) 
df %>% 
    group_by(group) %>% 
    mutate(cs = x + lag(x, 1, 0) + lag(x, 2, 0) + lag(x, 3, 0)) %>% 
    ungroup() 

, die das gewünschte Ergebnis liefert:

# A tibble: 10 x 3 
    group  x cs 
    <fctr> <dbl> <dbl> 
1  A  1  1 
2  B  3  3 
3  A  4  5 
4  B  7 10 
5  A  9 14 
6  B 10 20 
7  A 17 31 
8  B 29 49 
9  A 30 60 
10  B 55 101 

Gibt es einen kürzeren Weg, dies zu erreichen? (Hier habe ich vier Werte berechnet, aber ich brauche zwölf oder mehr).

+0

wollen Sie es für die ganze Gruppe? wie Cumsum? oder nur um die Anzahl der Perioden zurückbleiben? –

Antwort

4

Vielleicht könnten Sie verwenden, um die purrr Funktionen reduce und map mit dem tidyverse enthalten:

library(tidyverse) 
df <- data.frame(group = rep(c("A", "B"), 5), 
       x = c(1, 3, 4, 7, 9, 10, 17, 29, 30, 55)) 

df %>% 
    group_by(group) %>% 
    mutate(cs = reduce(map(0:3, ~ lag(x, ., 0)), `+`)) %>% 
    ungroup() 
#> # A tibble: 10 x 3 
#>  group  x cs 
#> <fctr> <dbl> <dbl> 
#> 1  A  1  1 
#> 2  B  3  3 
#> 3  A  4  5 
#> 4  B  7 10 
#> 5  A  9 14 
#> 6  B 10 20 
#> 7  A 17 31 
#> 8  B 29 49 
#> 9  A 30 60 
#> 10  B 55 101 

Um zu sehen, was passiert hier ist es wahrscheinlich einfacher, mit einem einfacheren Beispiel zu sehen, die nicht eine Gruppe benötigt .

v <- 1:5 
lagged_v <- map(0:3, ~ lag(v, ., 0)) 
lagged_v 
#> [[1]] 
#> [1] 1 2 3 4 5 
#> 
#> [[2]] 
#> [1] 0 1 2 3 4 
#> 
#> [[3]] 
#> [1] 0 0 1 2 3 
#> 
#> [[4]] 
#> [1] 0 0 0 1 2 

reduce(lagged_v, `+`) 
#> [1] 1 3 6 10 14