2017-11-23 5 views
3

私は一定の期間にわたってサマリー(合計または平均)を計算するグループのデータをいくつか持っています。私はgroup_byでmutateを実行してから変数を操作しています。これはdplyr :: lagです。次に例を示します。目的の結果得rグループラグサム

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() 

# 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 

は、これを実現するために短い方法はありますか? (ここでは4つの値を計算しましたが、実際には12以上が必要です)。

+0

グループ全体にしたいですか? cumsumのような?またはxの後ろの数だけ遅れていますか? –

答えて

4

はおそらく、あなたがpurrr機能reduceとtidyverseに含まれmap使用することができます:ここで何が起こっているかを確認するには

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 

をそれがグループを必要としないシンプルな例で見て、おそらく簡単です。

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