具有在 R 中重新启动的条件的 cumsum

cumsum with a condition to restart in R

我有这个包含多列的数据集。我想在一个列上使用 cumsum() 来调节另一列上的总和。那就是当 X 发生时,我希望总和从零重新开始,但是,我还想对“x”事件行的编号求和。我会在示例中更精确。

inv     ass    port   G    cumsum(G)
i        x       2    1       1
i        x       2    0       1
i        x       0    1       2
i        x       3    0       0
i        x       3    1       1

所以在第 3 行,条件端口 == 0 发生了。我想 cumsum(G),但在第 3 行我仍然想对 G 的值求和并从下一行重新开始计数。

我正在使用 dplyr 来 group_by(投资者,资产),但我被困在这里,因为我正在做:

res1 <- res %>% 
  group_by(investor, asset) %>% 
  mutate(posdays = ifelse(operation < 0 & portfolio == 0, 0, cumsum(G))) %>% 
            ungroup() 

自此重新启动 cumsum() 但不包括第 3 行的总和。 我想说的是“cumsum(G) 但是当前一行中的条件为“x”时,重新开始下一行中的总和。

你能帮帮我吗?

您也可以使用 cumsum 创建群组。

library(dplyr)

df <- df %>%
  group_by(group = cumsum(dplyr::lag(port == 0, default = 0))) %>%
  mutate(cumsum_G = cumsum(G)) %>%
  ungroup

df

#  inv   ass    port     G group cumsum_G
#  <chr> <chr> <int> <int> <dbl>    <int>
#1 i     x         2     1     0        1
#2 i     x         2     0     0        1
#3 i     x         0     1     0        2
#4 i     x         3     0     1        0
#5 i     x         3     1     1        1

您可以使用 %>% select(-group) 从输出中删除 group 列。

数据

df <- structure(list(inv = c("i", "i", "i", "i", "i"), ass = c("x", 
"x", "x", "x", "x"), port = c(2L, 2L, 0L, 3L, 3L), G = c(1L, 
0L, 1L, 0L, 1L)), class = "data.frame", row.names = c(NA, -5L))