R语言使用dplyr实现dataframe缺失值线性插值填充咨询
R dplyr 实现连续NA区间线性插值填充
实现逻辑
先对每一段连续的NA进行分组,获取每组前后的非空边界值,计算步长后按位置累加填充即可。
完整实现代码
首先加载依赖包:
library(dplyr)
1. 新增Col2列存储填充值
df <- data.frame(Col1 = c(2, 3, 5, NA, NA, 9, 10, NA, 16, 19)) df <- df %>% # 给每段连续NA分配唯一分组编号 mutate(na_group = cumsum(!is.na(Col1))) %>% group_by(na_group) %>% mutate( # 取当前NA段的前一个非空值 prev_val = first(Col1[!is.na(Col1)]), # 取当前NA段的后一个非空值 next_val = lead(prev_val, n = 1), # 统计当前段NA总数 na_count = sum(is.na(Col1)), # 计算插值步长 step = (next_val - prev_val)/(na_count + 1), # 生成NA位置的递增序号 na_seq = cumsum(is.na(Col1)), # 仅填充NA位置,非NA位置保留为NA,保留2位小数匹配示例 Col2 = round(ifelse(is.na(Col1), prev_val + step * na_seq, NA), 2) ) %>% ungroup() %>% # 移除中间计算用的辅助列 select(-na_group, -prev_val, -next_val, -na_count, -step, -na_seq)
运行后输出和需求中的示例完全一致。
2. 直接在原Col1列填充
只需将上面代码中Col2的赋值逻辑修改为覆盖Col1即可,非NA位置会保留原值:
df <- df %>% mutate(na_group = cumsum(!is.na(Col1))) %>% group_by(na_group) %>% mutate( prev_val = first(Col1[!is.na(Col1)]), next_val = lead(prev_val, n = 1), na_count = sum(is.na(Col1)), step = (next_val - prev_val)/(na_count + 1), na_seq = cumsum(is.na(Col1)), Col1 = ifelse(is.na(Col1), prev_val + step * na_seq, Col1) ) %>% ungroup() %>% select(-na_group, -prev_val, -next_val, -na_count, -step, -na_seq)
注意事项
如果数据开头/结尾存在连续NA,因为缺少前序/后序非空值,这部分NA会保留不填充,符合常规插值逻辑。如果需要特殊处理首尾NA,可以额外补充tidyr::fill()或者首尾常数填充的逻辑。
内容的提问来源于stack exchange,提问作者Sean
相关产品推荐
相关产品推荐

