R语言:按Names分组,组内列含1时将0/NaN替换为1
问题处理需求
原始数据框
Names COL1 COL2 COL3 COL4 SP1 0 1 NaN LA SP1 0 1 NaN LE SP1 0 1 1 LI SP2 1 0 0 LO SP2 0 0 0 LU SP3 1 1 NaN LY SP3 1 1 NaN LZ
处理规则
按Names分组,对每个分组中的COL1、COL2和COL3执行以下操作:
- 若该列在分组内存在值为
1的行,则将该列中的0或NaN替换为1
示例说明:
- SP1分组中COL3存在1,因此该列的两个NaN替换为1
- SP2分组中COL1存在1,因此该列的0替换为1
目标结果
Names COL1 COL2 COL3 COL4 SP1 0 1 1 LA SP1 0 1 1 LE SP1 0 1 1 LI SP2 1 0 0 LO SP2 1 0 0 LU SP3 1 1 NaN LY SP3 1 1 NaN LZ
示例数据的dput格式
structure(list(Names = c("SP1", "SP1", "SP1", "SP2", "SP2", "SP3", "SP3"), COL1 = c(0L, 0L, 0L, 1L, 0L, 1L, 1L), COL2 = c(1L, 1L, 1L, 0L, 0L, 1L, 1L), COL3 = c(NaN, NaN, 1, 0, 0, NaN, NaN), COL4 = c("LA", "LE", "LI", "LO", "LU", "LY", "LZ")), class = "data.frame", row.names = c(NA, -7L))
解决方案
使用dplyr包实现分组替换逻辑:
library(dplyr) # 加载数据 df <- structure(list(Names = c("SP1", "SP1", "SP1", "SP2", "SP2", "SP3", "SP3"), COL1 = c(0L, 0L, 0L, 1L, 0L, 1L, 1L), COL2 = c(1L, 1L, 1L, 0L, 0L, 1L, 1L), COL3 = c(NaN, NaN, 1, 0, 0, NaN, NaN), COL4 = c("LA", "LE", "LI", "LO", "LU", "LY", "LZ")), class = "data.frame", row.names = c(NA, -7L)) # 分组处理数据 df_processed <- df %>% group_by(Names) %>% mutate(across(c(COL1, COL2, COL3), ~{ # 判断组内该列是否存在1(忽略NaN) has_one <- any(.x == 1, na.rm = TRUE) if (has_one) { # 替换0和NaN为1 case_when( .x == 0 | is.na(.x) ~ 1, TRUE ~ .x ) } else { .x } })) %>% ungroup() # 输出结果 print(df_processed)
代码说明
group_by(Names):按Names字段分组across(c(COL1, COL2, COL3), ...):对指定列批量执行处理逻辑any(.x == 1, na.rm = TRUE):忽略NaN的情况下,判断组内当前列是否存在值1case_when:根据条件替换值,存在1时将0和NaN替换为1,否则保留原数据
内容的提问来源于stack exchange,提问作者chippycentra
相关产品推荐
相关产品推荐

