我想基于mutliple列合并两个数据帧。这里基于df1中的列B和df2中来自X-Z的所有列,但是将列X中的值返回到V1。 像字典一样,如果a df1 $ B与df2 $ X匹配,则a返回df_merged $ V1,但是如果来自df1 $ B的c与c匹配df2 $ Y,则从df2 $ X返回b,是它的同义词等。只有df2 $ X可以返回到df_merged $ V1
DF1
A B
1 a
2 c
3 f
和df2
X Y Z
a NA NA
b c NA
d e f
merged_df
A V1
1 a
2 b
3 d
这是我的尝试:
merge(df1, df2, by.x="B", by.y=c("X", "Y", "Z"), all.x=T)
答案 0 :(得分:2)
您可以使用tidyverse
来执行此操作,或者您实际上可以使用类似哈希/字典的数据结构。在R中,没有本机哈希表类,但您可以利用hashmap
包,它在内部使用Rcpp
来创建类似哈希的对象:
library(tidyverse)
library(hashmap)
dict = df2 %>%
mutate_if(is.factor, as.character) %>%
mutate(Value = X) %>%
gather(Label, Key, -Value) %>%
na.omit() %>%
{hashmap(.$Key, .$Value)}
这为您提供了一个哈希表:
> dict
## (character) => (character)
## [e] => [d]
## [d] => [d]
## [f] => [d]
## [b] => [b]
## [a] => [a]
现在,要使用df1$B
作为键提取值,只需执行以下操作:
dict[[df1$B]]
# [1] "a" NA "a" "d"
df1 %>%
mutate(Value = dict[[B]]) %>%
na.omit() %>%
select(-B)
<强>结果:强>
A Value
1 1 a
3 3 a
4 4 d
数据:强>
df1 = read.table(text = "A B
1 a
2 c
3 a
4 e", header = TRUE, stringsAsFactors = TRUE)
df2 = read.table(text = "X Y Z
a NA NA
b NA NA
d e f", header = TRUE, stringsAsFactors = TRUE)
答案 1 :(得分:1)
以下是用于演示目的的通用版本,但与使用hashmap
相比,此方法不够稳健,灵活性差且效率低:
library(tidyverse)
df2 %>%
mutate(Value = X) %>%
gather(Label, Key, -Value) %>%
split(.$Label) %>%
map_dfr(~ cbind(A = na.omit(match(.$Key, df1$B)),
slice(., match(df1$B, .$Key)))) %>%
select(A, Value) %>%
arrange(A)
<强>结果:强>
A Value
1 1 a
2 3 d
3 4 d
数据:强>
df1 = read.table(text = "A B
1 a
2 c
3 f
4 e", header = TRUE, stringsAsFactors = FALSE)
df2 = read.table(text = "X Y Z
a NA NA
b NA NA
d e f", header = TRUE, stringsAsFactors = FALSE)
注意:强>
我首先复制df2$X
因为它在技术上也是一个关键。然后,我将df2
改为长格式,split
改为Key
。对于每个密钥,我sliced
与df2$B
和rbind
匹配的行与map_dfr
一起。最后,仅返回Value
列。
请注意,我在此示例中使用了与df1
示例中不同的hashmap
,因为如果df1$B
有重复项,此方法将无效。