如何仅填充观测值之间的NA?tidyr::fill无法满足需求
问题描述
原始数据集:
| ID | Number |
|---|---|
| AX | 1 |
| AX | NA |
| AX | NA |
| AX | 2 |
| AX | NA |
| AX | NA |
| AX | NA |
预期处理后的数据:
| ID | Number |
|---|---|
| AX | 1 |
| AX | 1 |
| AX | 1 |
| AX | 2 |
| AX | NA |
| AX | NA |
| AX | NA |
使用tidyr::fill(DF, Number)会填充所有后续NA,无法保留末尾的空缺。需要仅填充实际观测值之间的NA,即第一个非NA值到最后一个非NA值之间的空缺,末尾NA保持不变。
解决方案
单组数据处理
先定位最后一个非NA值的位置,仅对该位置之前的行进行填充:
library(dplyr) library(tidyr) # 找到最后一个非NA的行号 last_non_na <- max(which(!is.na(DF$Number))) # 仅填充前last_non_na行的NA,保留后续空缺 DF_processed <- DF %>% mutate(Number = if_else(row_number() <= last_non_na, fill(Number, .direction = "down")$Number, Number))
也可以用切片拼接的方式实现:
DF_processed <- DF %>% slice(1:last_non_na) %>% fill(Number, .direction = "down") %>% bind_rows(DF %>% slice((last_non_na + 1):n()))
多分组数据处理(按ID分组)
如果数据包含多个分组,按组计算每个组的最后非NA位置:
DF_processed <- DF %>% group_by(ID) %>% mutate(last_non_na = max(which(!is.na(Number)))) %>% mutate(Number = if_else(row_number() <= last_non_na, fill(Number, .direction = "down")$Number, Number)) %>% select(-last_non_na) %>% ungroup()
通过上述方法,可精准控制填充范围,只填补观测值之间的空缺,末尾NA保持原样。
内容的提问来源于stack exchange,提问作者Rgrvkfer
相关产品推荐
相关产品推荐

