2017-08-29 41 views
4

我試圖比較多個矢量以查看它們之間的匹配值。我想將這些向量組合成一個表格,其中每列或者具有相同的值(對於匹配)或者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 

我試圖使載體dataframes和使用mergejoindplyrcbindcbind.fill,但所有這些要麼返回單列或不匹配所有行的值。

用R得到這個結果的最好方法是什麼?

回答

5

一個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") 
+0

只需添加'[-1]'在你的函數結束。 – Masoud

+0

@Masoud謝謝,我想說清楚'Reduce'實際上在做什麼 – useR

5

您可以使用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"