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

如何在R中用purrr::accumulate实现带双条件的累加计算?

累加和计算问题的解决思路

需求说明

需要实现带约束的累加逻辑:

  • 每次迭代累加固定常量,累加和总值不得超过400
  • 当累加和达到400后:
    • 夜间(22:00-次日6:00)保持400不变
    • 白天(6:00-22:00)重置为0,重新开始累加

原代码问题分析

你当前代码的核心问题是:accumulate()中引用的time2是整个列向量,而非当前迭代对应的时间值。accumulate()的回调函数默认仅能获取上一次累加结果(.x)和当前待累加值(.y),无法直接调用当前行的时间变量,导致时间判断逻辑完全失效,出现要么持续保持400、要么无视昼夜直接重置的问题。

解决方案

方法1:使用accumulate2()传递时间变量

purrr::accumulate2()支持同时传入两个输入序列,刚好可以将时间变量同步传递到回调函数中,实现逐行的时间判断:

library(tidyverse)

k_in = 2                              # 每次迭代的累加常量
tmax = 24*2*60                        # 两天的分钟数
x <- tibble(time = c(1:tmax),         # 时间(分钟)
            time_h = time/60,         # 时间(小时)
            time2 = (time_h %% 24),   # 归一化到0-24小时
            value = rep(k_in, tmax))  # 待累加值

# 使用accumulate2同时传递value和time2
x <- x %>%
  mutate(Sum = accumulate2(value, time2, 
                           function(prev_sum, curr_val, curr_time) {
                             if (prev_sum + curr_val <= 400) {
                               prev_sum + curr_val
                             } else {
                               # 判断当前时间是否处于夜间
                               if (curr_time >= 22 | curr_time < 6) {
                                 prev_sum  # 夜间保持400
                               } else {
                                 curr_val  # 白天重置后累加当前值(即从2开始)
                               }
                             }
                           },
                           .init = 0) %>%  # 初始值设为0,去掉最后多余的初始值
           head(-1))

方法2:使用显式循环(更直观易调试)

如果函数式写法的逻辑不够清晰,可以用普通循环逐行处理,更便于调试多变量条件:

library(tibble)

k_in = 2
tmax = 24*2*60
x <- tibble(time = c(1:tmax),
            time_h = time/60,
            time2 = (time_h %% 24),
            value = rep(k_in, tmax))

# 初始化Sum列
x$Sum <- 0
for (i in 2:nrow(x)) {
  prev_sum <- x$Sum[i-1]
  curr_val <- x$value[i]
  curr_time <- x$time2[i]
  
  if (prev_sum + curr_val <= 400) {
    x$Sum[i] <- prev_sum + curr_val
  } else {
    if (curr_time >=22 | curr_time <6) {
      x$Sum[i] <- prev_sum
    } else {
      x$Sum[i] <- curr_val  # 重置为0后加当前值,即从2开始
    }
  }
}

逻辑验证

  • 累加和未到400时,正常执行累加操作
  • 累加和达到400后,夜间时段持续保持400
  • 进入白天时段后,立即重置为0并启动新的累加周期

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 03:05:20