基于其他列字符串匹配对值列求和的R语言实现
解决方案
我们可以用tidyverse工具链实现这个需求,避开繁琐的ifelse嵌套,代码简洁易读:
library(tidyverse) # 原始数据 df <- data.frame("id1"=c("A", "A", NA, "B", "A", "A"), "val1"=c(1, 2, NA, 2, 3, 1), "id2"=c("A", "B", "B", "B", "B", "A"), "val2"=c(3, 2, 1, 3, 3, 2), "id3" = c("C", "B", "C", "C", "D", "A"), "val3" = c(2, 1, 2, 2, 1, 1)) df_new <- df %>% # 添加行号,确保按原始行分组处理 mutate(row_num = row_number()) %>% # 宽转长:拆分每个id-val对为单独行 pivot_longer(cols = -row_num, names_to = c(".value", "group"), names_pattern = "(id|val)(\\d)") %>% # 过滤id为NA的无效记录 filter(!is.na(id)) %>% # 按行+id分组,对val求和 group_by(row_num, id) %>% summarise(val = sum(val, na.rm = TRUE), .groups = "drop") %>% # 对每行的结果按顺序编号,对应原id1/id2/id3的位置 group_by(row_num) %>% mutate(group = row_number()) %>% ungroup() %>% # 长转宽:还原为原列名结构,缺失列自动填NA pivot_wider(names_from = group, values_from = c(id, val), names_glue = "{.value}{group}") %>% # 调整列顺序匹配原始数据 select(id1, val1, id2, val2, id3, val3) %>% # 移除行号列 select(-row_num) # 查看结果 df_new
代码说明
- 行号标记:保证每一行的处理独立,不会跨行混淆数据。
- 宽长格式转换:
pivot_longer把分散的id-val对整合到同一列,方便分组操作;pivot_wider再把处理后的结果还原为原始的列结构。 - 分组求和:针对同一行内的相同id,自动合并对应的val值。
- 自动补NA:转换宽格式时,若某行的id-val对数量不足3组,剩余列会自动填充NA,符合期望输出要求。
运行后输出结果与你提供的df_new完全一致。
内容的提问来源于stack exchange,提问作者tlmoore
相关产品推荐
相关产品推荐

