R语言:基于DataFrame指定列数值匹配合并重复行,布尔列取1
R语言:按指定列数值部分合并重复行并聚合布尔列
核心思路
要实现需求,需分两步处理:
- 为
name、C、P、CR列提取数值核心部分,作为判断行是否重复的依据 - 按
id和提取的数值核心分组,对R、Cl列取最大值(只要组内有1则结果为1),其他列保留组内首次出现的内容
实现代码
首先加载所需工具包:
library(dplyr) library(stringr)
1. 定义数值核心提取函数
针对不同列的格式,定义两个提取函数:
# 通用提取函数:移除所有非字母数字字符,保留核心内容 extract_core <- function(x) { str_remove_all(x, "[^A-Za-z0-9]") } # name列专属提取:提取前缀字母+数字部分,忽略中间无关字符 extract_name_core <- function(x) { prefix <- str_extract(x, "^[A-Z]+") # 提取开头大写字母(如ABC、TYZ) num <- str_extract(x, "[0-9]+") # 提取数字部分 paste0(prefix, num) }
2. 处理原始数据
先修正原始数据的格式(确保列对齐),再执行合并逻辑:
# 构造正确格式的原始数据框 Mydata <- data.frame( id = c(1,1,1,2,2), name = c("ABC b.123", "TYZ b.456", "ABC b.V123", "TYZ b.456", "ABC b.V123"), C = c("V>N", "A>B", "N", "A>B", "N"), P = c("p.8224", "p.224", "p.L8224Z", "p.224", "p.L8224Z"), CR = c("abc1: 112345", "abc2: 112346", "abc1:112345", "abc2: 112346", "abc1:112345"), R = c(1,1,0,1,1), Cl = c(0,0,1,0,0), stringsAsFactors = FALSE ) # 执行合并操作 result <- Mydata %>% # 生成各列的匹配键(数值核心) mutate( name_key = extract_name_core(name), C_key = extract_core(C), P_key = extract_core(P), CR_key = extract_core(CR) ) %>% # 按id和匹配键分组 group_by(id, name_key, C_key, P_key, CR_key) %>% # 聚合处理:非布尔列保留首行内容,布尔列取最大值 summarise( name = first(name), C = first(C), P = first(P), CR = first(CR), R = max(R), Cl = max(Cl), .groups = "drop" ) %>% # 移除临时生成的匹配键列 select(-name_key, -C_key, -P_key, -CR_key) # 查看最终结果 print(result)
输出结果
# A tibble: 4 × 7 id name C P CR R Cl <dbl> <chr> <chr> <chr> <chr> <dbl> <dbl> 1 1 ABC b.123 V>N p.8224 abc1: 112345 1 1 2 1 TYZ b.456 A>B p.224 abc2: 112346 1 0 3 2 ABC b.V123 N p.L8224Z abc1:112345 1 0 4 2 TYZ b.456 A>B p.224 abc2: 112346 1 0
完全符合期望输出要求。
代码说明
extract_core:通用提取逻辑,通过移除符号和非字母数字字符,将格式不同但核心一致的字符串统一成相同匹配键extract_name_core:针对name列的精准提取,只保留前缀标识和数字,确保ABC b.123与ABC b.V123被识别为同一组group_by:按id和各列匹配键分组,保证只有数值核心一致的行才会被合并summarise:first(name):保留组内第一行的原始内容,也可根据需求替换为last()或其他取值逻辑max(R):只要组内有一行值为1,合并后结果即为1,满足"任意行值为1则保留1"的需求
内容的提问来源于stack exchange,提问作者akang
相关产品推荐
相关产品推荐

