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

R data.table按条件向前填充指定行数的ID值问题

问题

我正在处理如下格式的数据集:

Date         ID    diff
    2020-01-01   NA    NA
    2020-01-02   NA    NA
    2020-01-03   NA    NA
    2020-01-04   NA    NA
    2020-01-05   1     NA
    2020-01-06   NA    NA
    2020-01-07   NA    NA
    2020-01-08   NA    NA
    2020-01-09   2     4
    2020-01-10   NA    NA
    2020-01-11   NA    NA
    2020-01-12   NA    NA
    2020-01-13   NA    NA
    2020-01-14   NA    NA
    2020-01-15   3     6
    2020-01-16   NA    NA
    2020-01-17   NA    NA
    2020-01-18   NA    NA
    2020-01-19   4     4
    2020-01-20   NA    NA

需求是将ID值向前填充diff列数值减1行,例如当ID为4、diff为4时,需将其前3行的ID填充为4,期望得到如下结果:

Date         ID    diff
    2020-01-01   NA    NA
    2020-01-02   NA    NA
    2020-01-03   NA    NA
    2020-01-04   NA    NA
    2020-01-05   1     NA
    2020-01-06   2     NA
    2020-01-07   2     NA
    2020-01-08   2     NA
    2020-01-09   2     4
    2020-01-10   3     NA
    2020-01-11   3     NA
    2020-01-12   3     NA
    2020-01-13   3     NA
    2020-01-14   3     NA
    2020-01-15   3     6
    2020-01-16   4     NA
    2020-01-17   4     NA
    2020-01-18   4     NA
    2020-01-19   4     4
    2020-01-20   NA    NA

我尝试使用lag函数,但无法实现连续行数的填充,请问有更合适的函数或方法吗?

解决方案

方法1:tidyverse工具链实现(dplyr + tidyr)

核心思路是先标记需要填充的行范围,再对区间内的ID批量赋值:

library(dplyr)
library(tidyr)

# 给数据集添加行号,方便定位填充区间
df <- df %>% mutate(row_num = row_number())

# 提取所有有有效ID和diff的行,计算出需要填充的起始行和结束行
fill_ranges <- df %>%
  filter(!is.na(ID) & !is.na(diff)) %>%
  mutate(start_row = row_num - (diff - 1),
         end_row = row_num) %>%
  select(start_row, end_row, ID)

# 遍历每个填充区间,给对应行的ID赋值
for (i in 1:nrow(fill_ranges)) {
  df$ID[fill_ranges$start_row[i]:fill_ranges$end_row[i]] <- fill_ranges$ID[i]
}

# 移除临时添加的行号列
df <- df %>% select(-row_num)

方法2:data.table高效实现(适合大数据集)

data.table的区间赋值语法更简洁,处理大数据时性能更优:

library(data.table)

# 转换为data.table格式
setDT(df)
# 添加行号
df[, row_num := .I]

# 生成填充规则:起始行、结束行、对应的ID值
fill_rules <- df[!is.na(ID) & !is.na(diff), .(start = row_num - (diff - 1), end = row_num, ID = ID)]

# 遍历规则,对每个区间的ID进行赋值
for (rule in fill_rules) {
  df[row_num %between% c(rule$start, rule$end), ID := rule$ID]
}

# 删除临时行号列
df[, row_num := NULL]

方法3:纯基础R实现(无需第三方包)

如果不想依赖任何外部包,用基础R也能完成:

# 添加行号列
df$row_num <- 1:nrow(df)

# 筛选出所有有有效ID和diff的行的索引
target_indices <- which(!is.na(df$ID) & !is.na(df$diff))

# 遍历每个目标行,计算填充范围并赋值
for (idx in target_indices) {
  current_id <- df$ID[idx]
  fill_length <- df$diff[idx] - 1
  # 确保起始行不小于1,避免越界
  start_idx <- max(1, idx - fill_length)
  df$ID[start_idx:idx] <- current_id
}

# 移除临时行号列
df$row_num <- NULL

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 20:25:30