Вот вариант с table
и colCumsums
library(matrixStats)
nm1 <- paste0("cumsum_", unique(df1$group))
df1[nm1] <- colCumsums(table(seq_len(nrow(df1)),df1$group) * df1$value)
df1
# time group value cumsum_A cumsum_B
#1 0 A 0 0 0
#2 0 B 0 0 0
#3 0 A 0 0 0
#4 1 A 0 0 0
#5 1 B 1 0 1
#6 1 B 0 0 1
#7 2 B 1 0 2
#8 2 A 1 1 2
#9 2 A 1 2 2
#10 2 A -1 1 2
#11 3 A 0 1 2
#12 3 B 1 1 3
Или другой вариант model.matrix
colCumsums((model.matrix(~ group -1, df1)) * df1$value)
Или model.matrix
с tidyverse
library(tidyverse)
df1 %>%
model.matrix( ~group - 1, .) %>%
as_tibble %>%
mutate_all(~ cumsum(. * df1$value)) %>%
rename_all(~ str_replace(., "group", "cumsum")) %>%
bind_cols(df1, .)
# time group value cumsumA cumsumB
#1 0 A 0 0 0
#2 0 B 0 0 0
#3 0 A 0 0 0
#4 1 A 0 0 0
#5 1 B 1 0 1
#6 1 B 0 0 1
#7 2 B 1 0 2
#8 2 A 1 1 2
#9 2 A 1 2 2
#10 2 A -1 1 2
#11 3 A 0 1 2
#12 3 B 1 1 3
или с использованием count
вместе с spread
df1 %>%
mutate(rn = row_number()) %>%
dplyr::count(group, rn) %>%
mutate(group = str_c("cumsum", group)) %>%
spread(group, n, fill = 0) %>%
mutate_at(-1, ~ cumsum(. * df1$value)) %>%
select(-rn) %>%
bind_cols(df1, .)
data
df1 <- structure(list(time = c(0L, 0L, 0L, 1L, 1L, 1L, 2L, 2L, 2L, 2L,
3L, 3L), group = c("A", "B", "A", "A", "B", "B", "B", "A", "A",
"A", "A", "B"), value = c(0L, 0L, 0L, 0L, 1L, 0L, 1L, 1L, 1L,
-1L, 0L, 1L)), class = "data.frame", row.names = c(NA, -12L))