每个主题的每个时期的前几个时期的总和 - R

Sum over previous periods for each period for each subject - R

一个MWE如下:

library(dplyr)

Period <- c(1, 1, 1, 2, 2, 2, 3, 3, 3) 

Subject <- c(1, 2, 3, 1, 2, 3, 1, 2, 3)

set.seed(1)
Values <- round(rnorm(n=9,mean=5,sd=1), digits = 2)

df <- bind_cols(Period = Period, Subject = Subject, Values = Values)
df
# A tibble: 9 x 3
  Period Subject Values
   <dbl>   <dbl>  <dbl>
1      1       1   4.37
2      1       2   5.18
3      1       3   4.16
4      2       1   6.6 
5      2       2   5.33
6      2       3   4.18
7      3       1   5.49
8      3       2   5.74
9      3       3   5.58

我想要一个变量 sum_values 来汇总每个时期每个主题的所有先前值。例如,第 2 期的科目 1 sum_values = 4.37,第 3 期将是 4.37+6.6 = 10.97

我可以用 for 循环来完成,这会非常乏味,涉及许多 if-else 语句,但我相信在 R 中有一个简单的方法。我怎样才能在 R 中更轻松地实现我的目的?

Period排列数据,用cumsum得到Values的累加和。因为你想总结所有以前的 Values 使用 lag.

library(dplyr)

df %>%
  arrange(Subject, Period) %>%
  group_by(Subject) %>%
  mutate(Values = lag(cumsum(Values), default = 0)) %>%
  ungroup


#  Period Subject Values
#1      1       1   0.00
#2      2       1   4.37
#3      3       1  10.97
#4      1       2   0.00
#5      2       2   5.18
#6      3       2  10.51
#7      1       3   0.00
#8      2       3   4.16
#9      3       3   8.34

您也可以使用 data.table 来完成此操作。

library(data.table)

Period <- c(1, 1, 1, 2, 2, 2, 3, 3, 3) 
Subject <- c(1, 2, 3, 1, 2, 3, 1, 2, 3)
set.seed(1)
Values <- round(rnorm(n=9,mean=5,sd=1), digits = 2)

# create data.table 
dt <- data.table(Period = Period, Subject = Subject, Values = Values)
# create cumsum by Subject
dt[,sum_values := shift(cumsum(Values),n = 1, fill = 0), by = Subject]

dt
#>    Period Subject Values sum_values
#> 1:      1       1   4.37       0.00
#> 2:      1       2   5.18       0.00
#> 3:      1       3   4.16       0.00
#> 4:      2       1   6.60       4.37
#> 5:      2       2   5.33       5.18
#> 6:      2       3   4.18       4.16
#> 7:      3       1   5.49      10.97
#> 8:      3       2   5.74      10.51
#> 9:      3       3   5.58       8.34