如何在R数据框中仅将相同非NA值之间的NA替换为前一个非NA值
实现思路
- 对每一列数值列单独处理,先记录所有非NA值的位置和对应取值
- 检查相邻两个非NA值是否相等:如果相等,就将两个值中间的所有NA填充为前一个非NA的取值;如果不相等则不填充
代码实现
tidyverse 版本(简洁易读)
library(dplyr) library(tidyr) # 读入示例数据 df <- structure(list(data_gas = structure(c(12779, 12780, 12781, 12786, 12787, 12788, 12789, 12793, 12794, 12795, 12800, 12801, 12802, 12807, 12808, 12809, 12814, 12815, 12816, 12822), class = "Date"), `1` = c(NA, 2.299, NA, NA, NA, 2.299, NA, NA, 2.299, NA, NA, 2.299, NA, NA, NA, 2.299, 2.299, NA, NA, NA), `3` = c(NA, 2.349, NA, NA, NA, NA, NA, NA, 2.349, NA, NA, NA, NA, NA, 2.369, NA, NA, NA, NA, NA), `4` = c(NA, 2.348, NA, NA, NA, NA, NA, NA, 2.348, NA, NA, NA, NA, NA, 2.368, NA, NA, NA, NA, NA)), row.names = c(NA, 20L), class = "data.frame") # 重命名列名和示例匹配,可根据自己实际数据集调整 colnames(df) <- c("date", "1", "2", "3") # 自定义符合要求的填充函数 fill_between_same <- function(x) { # 提取所有非NA值的位置和取值 non_na_pos <- which(!is.na(x)) non_na_val <- x[non_na_pos] # 遍历相邻非NA值对 for (i in seq_len(length(non_na_val) - 1)) { if (non_na_val[i] == non_na_val[i + 1]) { start <- non_na_pos[i] + 1 end <- non_na_pos[i + 1] - 1 if (start <= end) { # 相同值中间的NA全部填充 x[start:end] <- non_na_val[i] } } } return(x) } # 对所有数值列应用填充函数 df_result <- df %>% mutate(across(-date, fill_between_same)) # 查看输出结果 print(df_result, n = 20)
基础R版本(无需加载额外包)
# 读入示例数据 df <- structure(list(data_gas = structure(c(12779, 12780, 12781, 12786, 12787, 12788, 12789, 12793, 12794, 12795, 12800, 12801, 12802, 12807, 12808, 12809, 12814, 12815, 12816, 12822), class = "Date"), `1` = c(NA, 2.299, NA, NA, NA, 2.299, NA, NA, 2.299, NA, NA, 2.299, NA, NA, NA, 2.299, 2.299, NA, NA, NA), `3` = c(NA, 2.349, NA, NA, NA, NA, NA, NA, 2.349, NA, NA, NA, NA, NA, 2.369, NA, NA, NA, NA, NA), `4` = c(NA, 2.348, NA, NA, NA, NA, NA, NA, 2.348, NA, NA, NA, NA, NA, 2.368, NA, NA, NA, NA, NA)), row.names = c(NA, 20L), class = "data.frame") colnames(df) <- c("date", "1", "2", "3") fill_between_same <- function(x) { non_na_pos <- which(!is.na(x)) non_na_val <- x[non_na_pos] for (i in seq_len(length(non_na_val) - 1)) { if (non_na_val[i] == non_na_val[i + 1]) { start <- non_na_pos[i] + 1 end <- non_na_pos[i + 1] - 1 if (start <= end) { x[start:end] <- non_na_val[i] } } } return(x) } # 对除日期列外的所有列应用函数 df[, -1] <- lapply(df[, -1], fill_between_same)
以上代码运行后输出结果和你给出的理想输出完全一致。
内容的提问来源于stack exchange,提问作者moreirasd
相关产品推荐
相关产品推荐

