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

按ID组填充第一个非NA值之前的age列缺失值(NA)

问题:分组填充首个非NA值之前的缺失值

我有一个按id字段分组的数据框,age列存在缺失值NA。需求是每个id组内,仅对第一个非NA值之前的age列缺失值进行向上填充(fill up)。

示例数据

data <- data.frame(id=c(1,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3),
                   age=c(NA,6,NA,8,NA,NA,NA,NA,3,8,NA,NA,NA,7,NA,9))

原始数据展示:

id age
1   1  NA
2   1   6 # id=1的首个非NA值,从此处向上填充
3   1  NA
4   1   8
5   1  NA
6   1  NA
7   2  NA
8   2  NA
9   2   3 # id=2的首个非NA值,从此处向上填充
10  2   8
11  2  NA
12  3  NA
13  3  NA
14  3   7 # id=3的首个非NA值,从此处向上填充
15  3  NA
16  3   9

预期输出

id age
1   1   6
2   1   6
3   1  NA
4   1   8
5   1  NA
6   1  NA
7   2   3
8   2   3
9   2   3
10  2   8
11  2  NA
12  3   7
13  3   7
14  3   7
15  3  NA
16  3   9

你尝试的代码

library(dplyr)
library(tidyr)

data1 <- data %>% group_by(id) %>%  
  fill(!is.na(age[1]), .direction = "up")

这段代码存在逻辑错误:fill函数的第一个参数需要指定要填充的列名,而非逻辑判断表达式,因此无法实现预期效果。

正确解决方案

通过分组标记需要填充的行,再针对性替换缺失值:

library(dplyr)

data_processed <- data %>%
  group_by(id) %>%
  mutate(
    # 获取每组首个非NA的age值
    first_valid_age = first(age[!is.na(age)]),
    # 标记首个非NA值之前的所有行
    is_before_first_valid = cumsum(!is.na(age)) == 0,
    # 对标记行填充首个非NA值,其余行保留原值
    age = ifelse(is_before_first_valid, first_valid_age, age)
  ) %>%
  # 移除临时辅助列
  select(-first_valid_age, -is_before_first_valid) %>%
  ungroup()

# 查看结果
print(data_processed)

代码说明

  1. first(age[!is.na(age)]):提取每个分组中第一个非缺失的age值;
  2. cumsum(!is.na(age)) == 0:通过累加非NA值的计数,判断当前行是否处于首个非NA值之前(累加和为0则是);
  3. ifelse语句:仅对标记的行填充首个非NA值,其余行保持原age值不变。

运行后输出与预期完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 06:27:25