使用R中的哈希表/字典将值替换为值

时间:2017-11-02 14:46:10

标签: r dictionary dataframe merge hashtable

我想基于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)

2 个答案:

答案 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。对于每个密钥,我sliceddf2$Brbind匹配的行与map_dfr一起。最后,仅返回Value列。

请注意,我在此示例中使用了与df1示例中不同的hashmap,因为如果df1$B有重复项,此方法将无效。