如何在R中批量处理多列对,用_2列值替换_1列的NA?
批量替换DataFrame中_1列的NA为对应_2列的值
Base R 解决方案
方法1:循环处理前缀分组
先提取所有列的前缀(比如y、z),然后循环每个前缀对应的列对,替换_1列的NA值:
# 示例数据 df <- data.frame(y_1 = c(1, NA, 2, 2), y_2 = c(1, 1, 2, 2), z_1 = c(4, 5, NA, 6), z_2 = c(4, 5, 5, 6)) # 提取所有列的前缀(去掉_1/_2后缀) prefixes <- unique(sub("_\\d+$", "", colnames(df))) # 循环处理每一组列对 for (prefix in prefixes) { col1 <- paste0(prefix, "_1") col2 <- paste0(prefix, "_2") # 将_1列的NA替换为_2列对应位置的值 df[[col1]] <- ifelse(is.na(df[[col1]]), df[[col2]], df[[col1]]) }
处理后结果:
> df y_1 y_2 z_1 z_2 1 1 1 4 4 2 1 1 5 5 3 2 2 5 5 4 2 2 6 6
方法2:用Map函数批量处理
如果想避免显式循环,可以用Map函数对列对进行批量操作:
# 将列按前缀分组,确保每组是_1和_2的顺序 col_groups <- split(colnames(df), sub("_\\d+$", "", colnames(df))) col_groups <- lapply(col_groups, function(x) x[order(x)]) # 提取所有_1列和_2列 cols_1 <- unlist(lapply(col_groups, `[`, 1)) cols_2 <- unlist(lapply(col_groups, `[`, 2)) # 批量替换NA df[cols_1] <- Map(function(x, y) ifelse(is.na(x), y, x), df[cols_1], df[cols_2])
tidyverse 解决方案(dplyr)
如果你习惯用tidyverse工具链,可以用across结合cur_column()动态匹配对应列:
library(dplyr) df <- df %>% mutate(across(ends_with("_1"), ~ ifelse(is.na(.), get(sub("_1$", "_2", cur_column())), .)))
这个方法会自动匹配所有以_1结尾的列,找到对应的_2列完成NA替换。
内容的提问来源于stack exchange,提问作者reidj
相关产品推荐
相关产品推荐

