【问题标题】:Join vectors into dataframe by matching values通过匹配值将向量加入数据帧
【发布时间】:2018-02-07 09:34:16
【问题描述】:

我正在尝试比较多个向量以查看它们之间的匹配值。我想将向量组合成一个表,其中每一列都具有相同的值(匹配)或 NA(不匹配)。

例如:

list1 <- c("a", "b", "c", "d")
list2 <- c("a", "c", "d")
list3 <- c("a", "b", "c", "e", "f")  

应该变成:

a  a  a
b NA  b
c  c  c
d  d  NA
NA NA e
NA NA f

我尝试制作向量数据帧并使用来自dplyrcbindcbind.fillmergejoin,但所有这些要么返回单列,要么不匹配所有行的值.

使用 R 获得此结果的最佳方法是什么?

【问题讨论】:

    标签: r dataframe merge dplyr


    【解决方案1】:

    Base R 解决方案:

    df1 = data.frame(col = list1, list1)
    df2 = data.frame(col = list2, list2)
    df3 = data.frame(col = list3, list3)
    
    Reduce(function(x, y) merge(x, y, all=TRUE), list(df1, df2, df3))
    
    #   col list1 list2 list3
    # 1   a     a     a     a
    # 2   b     b  <NA>     b
    # 3   c     c     c     c
    # 4   d     d     d  <NA>
    # 5   e  <NA>  <NA>     e
    # 6   f  <NA>  <NA>     f
    

    结果:

    > Reduce(function(x, y) merge(x, y, all=TRUE), list(df1, df2, df3))[,-1]
      list1 list2 list3
    1     a     a     a
    2     b  <NA>     b
    3     c     c     c
    4     d     d  <NA>
    5  <NA>  <NA>     e
    6  <NA>  <NA>     f
    

    dplyr + purrr:

    library(dplyr)
    library(purrr)
    
    list(list1, list2, list3) %>%
      map(~ data.frame(col = ., ., stringsAsFactors = FALSE)) %>%
      reduce(full_join, by = "col") %>%
      select(-col) %>%
      setNames(paste0("list", 1:3))
    

    数据:

    list1 <- c("a", "b", "c", "d")
    list2 <- c("a", "c", "d")
    list3 <- c("a", "b", "c", "e", "f") 
    

    【讨论】:

    • 只需在函数末尾添加[,-1]
    • @Masoud 谢谢,我想弄清楚Reduce 实际在做什么
    【解决方案2】:

    您可以使用unlistunique 获取所有可能的值,然后在每个向量中找到它们的匹配项。如果没有匹配项,match 会像你想要的那样返回 NA

    list1 <- c("a", "b", "c", "d")
    list2 <- c("a", "c", "d")
    list3 <- c("a", "b", "c", "e", "f")
    list_of_lists <- list(
      list1 = list1,
      list2 = list2,
      list3 = list3
    )
    
    all_values <- unique(unlist(list_of_lists))
    
    fleshed_out <- vapply(
      list_of_lists,
      FUN.VALUE = all_values,
      FUN       = function(x) {
        x[match(all_values, x)]
      }
    )
    
    fleshed_out
    #    list1 list2 list3
    # [1,] "a"   "a"   "a"
    # [2,] "b"   NA    "b"
    # [3,] "c"   "c"   "c"
    # [4,] "d"   "d"   NA
    # [5,] NA    NA    "e"
    # [6,] NA    NA    "f"
    

    【讨论】:

      猜你喜欢
      • 2021-09-15
      • 2020-09-20
      • 1970-01-01
      • 2018-11-15
      • 1970-01-01
      • 1970-01-01
      • 2021-12-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多