如何在R中实现基于多列匹配的两个数据框合并?
实现多列匹配合并的正确方法
嘿,你的思路方向是对的,但直接用merge(df1,df2 by(P.X == P.X.1 | P.X.2 | P.X.3 | P.X.4))这种写法是行不通的——不管是R还是Python里的merge函数,by参数只能指定要匹配的列名,没法直接写这种多列匹配的逻辑条件。
核心思路是先把df2中P.X.1到P.X.4这四列转换成长格式(也就是把多列合并成一列),这样就能和df1的P.X列进行常规的等值匹配了。下面给你两种常见语言的具体实现:
R语言实现
首先先构造符合你描述的数据框:
df1 <- data.frame( P.X = c("OOPA", "POKA", "JKIO", "KOPP"), value = c(5, 4, 3, 1) ) df2 <- data.frame( P.X.1 = c("JKIO", "CX", "EDD", "KOPP"), P.X.2 = c("UIX", "OOPA", "POKA", "FOSI"), P.X.3 = c("HOP", NA, NA, NA), P.X.4 = c(NA, NA, NA, NA), mass = c(56, 44, 13, 11) )
然后用tidyr和dplyr包处理并合并:
library(tidyr) library(dplyr) # 把df2的P.X.1-P.X.4转成单列,过滤掉空值 df2_long <- df2 %>% pivot_longer(cols = starts_with("P.X."), names_to = "col_name", values_to = "match_col") %>% filter(!is.na(match_col)) %>% select(match_col, mass) # 只保留需要的列 # 合并df1和转换后的df2,去掉无匹配的行 result <- df1 %>% left_join(df2_long, by = c("P.X" = "match_col")) %>% drop_na() print(result)
输出结果:
P.X value mass 1 OOPA 5 44 2 POKA 4 13 3 JKIO 3 56 4 KOPP 1 11
Python语言实现
同样先构造数据框:
import pandas as pd df1 = pd.DataFrame({ 'P.X': ['OOPA', 'POKA', 'JKIO', 'KOPP'], 'value': [5, 4, 3, 1] }) df2 = pd.DataFrame({ 'P.X.1': ['JKIO', 'CX', 'EDD', 'KOPP'], 'P.X.2': ['UIX', 'OOPA', 'POKA', 'FOSI'], 'P.X.3': ['HOP', None, None, None], 'P.X.4': [None, None, None, None], 'mass': [56, 44, 13, 11] })
用pandas的melt方法转换格式后合并:
# 将df2的多列转成单列,过滤空值 df2_long = df2.melt( id_vars='mass', value_vars=['P.X.1', 'P.X.2', 'P.X.3', 'P.X.4'], var_name='col_name', value_name='match_col' ).dropna(subset=['match_col']) # 合并两个数据框,只保留需要的列 result = pd.merge(df1, df2_long, left_on='P.X', right_on='match_col', how='inner')[['P.X', 'value', 'mass']] print(result)
输出结果和R语言一致,完全符合你想要的结构。
内容的提问来源于stack exchange,提问作者user12237608
相关产品推荐
相关产品推荐

