【问题标题】:Merge 2 dataframes with values separated by commas in one of the dataframes合并 2 个数据帧,其中一个数据帧中的值由逗号分隔
【发布时间】:2018-06-01 17:06:14
【问题描述】:

我有 2 个这样的数据框

df1 <- data.frame(Colors = c("Yellow","Pink","Green","Blue","White","Red"
                            ,"Cyan","Brown","Violet","Orange","Gray"))

df2 <- data.frame(Colors = c("Yellow,Pink","Green","Gold","White","Red,Cyan,Brown",
                             "Violet","Magenta","Gray"))

我正在尝试合并这 2 个数据帧并返回 df2 中的行,这些行也存在于 df1 中。我还需要确保

我的想要的输出

          Colors
     Yellow,Pink
           Green
           White
  Red,Cyan,Brown
          Violet
            Gray

如果我这样做df &lt;- inner_join(df2,df1), 然后我没有得到Yellow,PinkRed,Cyan,Brown 的行

我在这里缺少什么?有人可以指出我正确的方向吗?

【问题讨论】:

  • "Yellow,Pink" 与 "Yellow","Pink" 不同,所以不会返回。
  • 红色、青色、棕色也一样。本质上,您正在尝试在这两个位置加入两个不同的字符串。连接通过匹配完全相同的 id 来操作

标签: r datatable dplyr


【解决方案1】:

在每个拆分项上使用pmatch 的基本R 解决方案:

split_list <- strsplit(as.character(df2$Colors),",")
keep_lgl   <- sapply(split_list,function(x) !anyNA(pmatch(x,df1$Colors)))
df2[keep_lgl,,drop=FALSE]

#           Colors
# 1    Yellow,Pink
# 2          Green
# 4          White
# 5 Red,Cyan,Brown
# 6         Violet
# 8           Gray

注意:只有当df1 中的所有颜色都可用时,我才会匹配一系列颜色。

一些tidyverse 接近:

library(tidyverse)
df2 %>% mutate(keep=Colors) %>%
  separate_rows(Colors) %>%
  add_count(keep) %>%
  inner_join(df1) %>%
  add_count(keep) %>% # doesn't do anything here but important in general
  filter(n==nn)   %>% # same
  distinct(keep)  %>%
  rename(Colors=keep)

# # A tibble: 6 x 1
# Colors
# <fctr>
# 1    Yellow,Pink
# 2          Green
# 3          White
# 4 Red,Cyan,Brown
# 5         Violet
# 6           Gray

df2 %>% mutate(keep=Colors) %>%
  separate_rows(Colors) %>%
  left_join(df1 %>% mutate(Colors2=Colors,.)) %>%
  group_by(keep) %>%
  summarize(filt=anyNA(Colors2)) %>%
  filter(!filt) %>%
  select(-2)

# # A tibble: 6 x 1
#             keep
#           <fctr>
# 1           Gray
# 2          Green
# 3 Red,Cyan,Brown
# 4         Violet
# 5          White
# 6    Yellow,Pink

【讨论】:

    【解决方案2】:

    您可以使用fuzzyjoin 包中的regex_inner_join 加入df1df2。最后,从df2 列中选择唯一的行。

    library(dplyr)
    library(fuzzyjoin)
    
    regex_inner_join(df2, df1, by=c(Colors = "Colors")) %>%
      select(Colors = Colors.x) %>% distinct()
    
    #           Colors
    # 1    Yellow,Pink
    # 2          Green
    # 3          White
    # 4 Red,Cyan,Brown
    # 5         Violet
    # 6           Gray
    
    # Just to demonstrate, result of joined tables using regex_inner_join. One,
    # can work-out to convert data in desired format afterwards.
    
    regex_inner_join(df2, df1, by=c(Colors = "Colors")) 
    #         Colors.x Colors.y
    # 1    Yellow,Pink   Yellow
    # 2    Yellow,Pink     Pink
    # 3          Green    Green
    # 4          White    White
    # 5 Red,Cyan,Brown      Red
    # 6 Red,Cyan,Brown     Cyan
    # 7 Red,Cyan,Brown    Brown
    # 8         Violet   Violet
    # 9           Gray     Gray
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-01
      • 2021-04-26
      • 1970-01-01
      相关资源
      最近更新 更多