You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在R语言中实现特定规则的滞后累积求和(lagged cumsum)

问题:计算累积差异值diff_calc

输入数据

df <- tibble(
  date= seq.Date(as.Date("2021-01-01"), as.Date("2022-02-01"), by = "month"),
  val1 = c(100, 100, 105, 125, 125, 125, 125, 132, 132, 132, 135, 150, 150, 150),
  val2 = c(100, 100, 100, 125, 125, 125, 125, 125, 125, 125, 125, 150, 150, 150),
  diff = val1-val2
)

数据预览:

date        val1  val2  diff
        <date>     <dbl> <dbl> <dbl>
      1 2021-01-01   100   100     0
      2 2021-02-01   100   100     0
      3 2021-03-01   105   100     5
      4 2021-04-01   125   125     0
      5 2021-05-01   125   125     0
      6 2021-06-01   125   125     0
      7 2021-07-01   125   125     0
      8 2021-08-01   132   125     7
      9 2021-09-01   132   125     7
     10 2021-10-01   132   125     7
     11 2021-11-01   135   125    10
     12 2021-12-01   150   150     0
     13 2022-01-01   150   150     0
     14 2022-02-01   150   150     0

需求说明

需要新增列diff_calc,规则如下:

  • diff_calc是diff中之前出现的唯一值的累积和;
  • 若连续出现多个唯一的diff值,取其中的最大值加上按相同规则计算的之前diff值的累积和。

期望输出

output <- tibble(
  date= seq.Date(as.Date("2021-01-01"), as.Date("2022-02-01"), by = "month"),
  val1 = c(100, 100, 105, 125, 125, 125, 125, 132, 132, 132, 135, 150, 150, 150),
  val2 = c(100, 100, 100, 125, 125, 125, 125, 125, 125, 125, 125, 150, 150, 150),
  diff = val1-val2,
  diff_calc = c(0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 15, 15, 15)
)

输出预览:

date        val1  val2  diff diff_calc
 <date>     <dbl> <dbl> <dbl>     <dbl>
 1 2021-01-01   100   100     0         0
 2 2021-02-01   100   100     0         0
 3 2021-03-01   105   100     5         0
 4 2021-04-01   125   125     0         5
 5 2021-05-01   125   125     0         5
 6 2021-06-01   125   125     0         5
 7 2021-07-01   125   125     0         5
 8 2021-08-01   132   125     7         5
 9 2021-09-01   132   125     7         5
10 2021-10-01   132   125     7         5
11 2021-11-01   135   125    10         5
12 2021-12-01   150   150     0        15
13 2022-01-01   150   150     0        15
14 2022-02-01   150   150     0        15

解决方案

使用dplyr包实现逻辑,代码如下:

library(dplyr)

df_result <- df %>%
  # 标记diff为0的行,并划分阶段:每次从非0回到0时标记为新阶段
  mutate(
    is_zero = diff == 0,
    stage = cumsum(is_zero & lag(is_zero, default = TRUE) == FALSE)
  ) %>%
  # 按阶段计算该阶段内非0 diff的最大值
  group_by(stage) %>%
  mutate(stage_max = ifelse(all(is_zero), 0, max(diff[!is_zero]))) %>%
  ungroup() %>%
  # 计算阶段最大值的累积和,滞后一个阶段用于赋值
  mutate(
    cumulative_sum = lag(cumsum(stage_max), default = 0),
    # 非0行用上一阶段累积和;0行用累积和加当前阶段最大值
    diff_calc = ifelse(is_zero, cumulative_sum + stage_max, cumulative_sum)
  ) %>%
  # 清理临时列
  select(-is_zero, -stage, -stage_max, -cumulative_sum)

print(df_result)

逻辑说明

  1. 阶段划分:通过is_zero标记diff为0的行,stage将数据划分为“非0区间+后续0区间”的组合阶段;
  2. 阶段最大值计算:每个阶段内若存在非0 diff,取这些值的最大值,否则为0;
  3. 累积赋值:
    • cumulative_sum是阶段最大值的累积和,但滞后一个阶段,确保当前行使用的是之前所有阶段的最大值总和;
    • 非0行的diff_calc使用上一阶段的累积和(未到结算点,暂不加入当前阶段最大值);
    • 0行的diff_calc使用累积和加上当前阶段的最大值(当前阶段的0区间是上一非0区间的结算点,需加入该区间的最大值)。

内容的提问来源于stack exchange,提问作者costebk08

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 12:45:12