R语言:按nodepair分组替换NA行并设置ES1列为NA
R语言分组填充NA并修改ES1列的实现方案
原始数据
Tab1 <- read.table(text = " nodepair ES1 ES2 ++ -- +- -+ 0+ +0 0- -0 00 1 E_A6 3 3 0 0 0 0 0 0 0 0 1 2 E_A6 4 3 NA NA NA NA NA NA NA NA NA 3 E_A6 5 3 NA NA NA NA NA NA NA NA NA 4 E_AL 3 3 0 5 0 0 0 0 0 0 1 5 E_AL 4 3 NA NA NA NA NA NA NA NA NA 6 E_AL 5 3 NA NA NA NA NA NA NA NA NA ", header = TRUE)
需求说明
按nodepair分组完成以下操作:
- 组内包含NA的行,用同组内ES1等于ES2且ES2与当前NA行ES2匹配的行的对应列值替换NA
- 将原NA行的
ES1列设为NA
期望结果
Tab2 <- read.table(text = " nodepair ES1 ES2 ++ -- +- -+ 0+ +0 0- -0 00 1 E_A6 3 3 0 0 0 0 0 0 0 0 1 2 E_A6 NA 3 0 0 0 0 0 0 0 0 1 3 E_A6 NA 3 0 0 0 0 0 0 0 0 1 4 E_AL 3 3 0 5 0 0 0 0 0 0 1 5 E_AL NA 3 0 5 0 0 0 0 0 0 1 6 E_AL NA 3 0 5 0 0 0 0 0 0 1 ", header = TRUE)
用户尝试的未完成代码
Tab2 <- Tab1 %>% rowwise %>% mutate(across(4:12, ~ifelse(is.na(rowsums), ???, .))))
正确实现代码
使用dplyr分组匹配参考行的方式可以高效实现需求:
library(dplyr) Tab2 <- Tab1 %>% group_by(nodepair, ES2) %>% mutate( # 用组内ES1==ES2的行的值填充4-12列的NA across(4:12, ~ifelse(is.na(.), .[ES1 == ES2][1], .)), # 对原含NA的行,将ES1设为NA ES1 = ifelse(rowSums(is.na(across(4:12))) > 0, NA, ES1) ) %>% ungroup()
代码解释
- 分组逻辑:按
nodepair+ES2分组,确保只匹配同组且ES2一致的行 - NA填充:对4到12列,若当前值为NA,取组内
ES1==ES2的参考行对应值(.[ES1 == ES2][1]保证取到唯一有效参考行) - 修改ES1列:通过统计4-12列的NA数量判断原行是否含NA,若是则将ES1设为NA
- 取消分组:最后取消分组回归普通数据框
运行后结果与预期的Tab2完全一致。
内容的提问来源于stack exchange,提问作者Hard_Course
相关产品推荐
相关产品推荐

