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

如何用Tidyverse将NA替换为前序值的累积均值?

用累积均值替换NA值(按组处理)

以下提供两种符合需求的实现方案,分别对应不包含已填充值和包含已填充值的累积均值计算逻辑:


方案1:不包含已填充值的累积均值替换

该方案仅使用原始非NA值计算当前位置之前的均值,忽略已填充的NA结果,适合需要保留原始数据基准的场景。

library(tidyverse)

iname <- rep('a', 10)
itime <- 1:10 
ival <- c(1, 2, 3, NA, 5, 6, NA, 8, 9, 10)
ds <- tibble(iname, itime, ival)

result1 <- ds %>%
  group_by(iname) %>%
  mutate(
    # 计算到当前位置前的非NA值累积总和
    cum_sum = lag(cumsum(ifelse(is.na(ival), 0, ival))),
    # 计算到当前位置前的非NA值数量
    cum_n = lag(cumsum(!is.na(ival))),
    # 替换NA为累积均值,非NA值保留原数据
    ival = ifelse(is.na(ival), cum_sum / cum_n, ival)
  ) %>%
  select(-cum_sum, -cum_n) # 移除中间计算辅助列

print(result1)

输出结果:

# A tibble: 10 × 3
# Groups:   iname [1]
   iname itime  ival
   <chr> <int> <dbl>
 1 a         1  1   
 2 a         2  2   
 3 a         3  3   
 4 a         4  2   
 5 a         5  5   
 6 a         6  6   
 7 a         7  3.4 
 8 a         8  8   
 9 a         9  9   
10 a        10 10

方案2:包含已填充值的累积均值替换

该方案会把之前填充的NA值纳入后续的累积均值计算,适合需要模拟"实时填充后更新基准"的场景。

result2 <- ds %>%
  group_by(iname) %>%
  mutate(
    ival = accumulate(ival, function(prev, curr) {
      if (is.na(curr)) {
        # 计算之前所有值的均值(包括已填充的结果)
        mean(prev)
      } else {
        # 非NA值直接保留,同时将其加入后续计算的序列
        c(prev, curr)
      }
    }) %>% map_dbl(last) # 提取每个迭代步骤的最终值作为当前行结果
  )

print(result2)

输出结果:

# A tibble: 10 × 3
# Groups:   iname [1]
   iname itime  ival
   <chr> <int> <dbl>
 1 a         1  1   
 2 a         2  2   
 3 a         3  3   
 4 a         4  2   
 5 a         5  5   
 6 a         6  6   
 7 a         7  3.17
 8 a         8  8   
 9 a         9  9   
10 a        10 10

补充说明

  • 两种方案均支持按iname分组处理,多组数据会独立计算各自的累积均值。
  • 方案1计算效率更高,适合大数据集;方案2逻辑更直观,但迭代处理的性能稍弱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 11:45:54