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

如何用Tidyverse工具(如purrr::map)替代循环填充n_j列NA值?

递推填充缺失值的Tidyverse解决方案

问题描述

现有数据集df,其中n_j列仅第一行有值,其余均为NA。需要通过公式n_j(当前行) = n_j(前一行) - (d_j(前一行) + c_j(前一行))填充所有缺失的n_j值。目前已通过for循环实现需求,希望改用purrr::map或其他Tidyverse函数完成。

数据创建代码

df = structure(list(time_intervals = structure(1:8, levels = c("[0,12)",
"[12,24)", "[24,36)", "[36,48)", "[48,60)", "[60,72)", "[72,84)",
"[84,96]"), class = "factor"), d_j = c(16L, 10L, 1L, 3L, 2L,
2L, 0L, 2L), c_j = c(4L, 4L, 0L, 1L, 2L, 0L, 1L, 0L), n_j = c(48L,
NA, NA, NA, NA, NA, NA, NA)), row.names = c(NA, -8L), class = c("tbl_df",
"tbl", "data.frame"))

已实现的for循环代码

for (i in 1:nrow(df)) {
  df <- df |> 
    mutate(
    n_j = ifelse(is.na(n_j), lag(n_j)- (lag(d_j)+lag(c_j)), n_j)
  )
}

Tidyverse替代方案

方法1:使用purrr::accumulate(推荐)

accumulate是purrr包中专门用于递推计算的函数,完美适配这种依赖前序结果的场景:

library(tidyverse)

df <- df |>
  mutate(
    n_j = accumulate(
      .init = first(n_j),
      1:(nrow(df)-1),
      ~ .x - (d_j[.y] + c_j[.y])
    )
  )
  • .init指定初始值为n_j的第一个有效值
  • 迭代范围1:(nrow(df)-1)对应需要计算的7行数据
  • 公式~ .x - (d_j[.y] + c_j[.y])中,.x代表前一行计算得到的n_j值,.y代表当前迭代的索引,取对应行的d_j和c_j求和后做减法

方法2:使用dplyr的累积求和

通过先计算每行的增量,再结合初始值做累积求和,同样可以实现需求:

library(dplyr)

df <- df |>
  mutate(
    # 计算每行的增量:前一行d_j+c_j的负值
    delta = -(d_j + c_j),
    # 初始值加上前n-1个增量的累积和
    n_j = first(n_j) + c(0, cumsum(delta[-nrow(df)]))
  ) |>
  select(-delta) # 移除临时增量列

说明

两种方法均避免了原for循环中反复赋值整个数据集的低效操作,属于Tidyverse生态内的向量化/递推计算方式,运行效率更高且代码更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 14:12:37