按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)
代码说明
first(age[!is.na(age)]):提取每个分组中第一个非缺失的age值;cumsum(!is.na(age)) == 0:通过累加非NA值的计数,判断当前行是否处于首个非NA值之前(累加和为0则是);ifelse语句:仅对标记的行填充首个非NA值,其余行保持原age值不变。
运行后输出与预期完全一致。
内容的提问来源于stack exchange,提问作者Yebelay Berehan
相关产品推荐
相关产品推荐

