R语言按附加条件关联合并两个data.frame的实现方法
R定制化合并两个data.frame实现方法
需求说明
需要以两个表的type2列值相等为匹配条件,将table1中type1列的取值(A/B/C/D)作为列名,匹配table2中对应同名列的取值,完成合并。
示例数据构造
# 第一个数据框 table1<-data.frame(type1=c("A","B","C","D"), type2=c("AAA","BBB","CCC","DDD") , value=seq(1:4) ) # 第二个数据框 table2<-data.frame( type2=c("AAA","BBB","CCC","DDD","FFF","GGG"), A= seq(1:6), B= seq(1:6), C= seq(1:6), D= seq(1:6), F= seq(1:6), G= seq(1:6) )
实现方法
方法1:Base R 实现(无需安装额外包)
核心逻辑是先按type2做左连接,再逐行根据type1的值索引table2对应列的取值:
# 按type2左连接,保留table1全部行 merge_tmp <- merge(table1, table2, by = "type2", all.x = TRUE) # 逐行提取type1对应列的值 merge_tmp$new_value <- mapply( function(col_name, row_idx) merge_tmp[row_idx, as.character(col_name)], merge_tmp$type1, seq_len(nrow(merge_tmp)) ) # 筛选保留需要的列,得到最终结果 result <- merge_tmp[, c("type1", "type2", "value", "new_value")]
运行后输出的result和预期结果完全一致:
| type1 | type2 | value | new_value |
|---|---|---|---|
| A | AAA | 1 | 1 |
| B | BBB | 2 | 2 |
| C | CCC | 3 | 3 |
| D | DDD | 4 | 4 |
方法2:tidyverse 实现(简洁易读)
如果日常使用tidyverse生态的包,可以用更简洁的管道操作实现:
library(dplyr) result <- table1 %>% # 按type2左连接table2 left_join(table2, by = "type2") %>% # 逐行处理,提取type1对应列的值 rowwise() %>% mutate(new_value = cur_data()[[as.character(type1)]]) %>% # 选择需要的列 select(type1, type2, value, new_value) %>% ungroup()
两种方法得到的结果完全相同,可以根据自己的使用习惯选择。
内容的提问来源于stack exchange,提问作者silent_hunter
相关产品推荐
相关产品推荐

