2017-08-29 2 views
4

Ich versuche, mehrere Vektoren zu vergleichen, um zu sehen, wo es passende Werte zwischen ihnen gibt. Ich möchte die Vektoren in eine Tabelle kombinieren, in der jede Spalte entweder den gleichen Wert (für Übereinstimmungen) oder NA (für keine Übereinstimmung) hat.Verbinden Sie Vektoren in Datenrahmen durch übereinstimmende Werte

Zum Beispiel:

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

Sollte sich:

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

Ich habe versucht, die Vektoren Datenrahmen Herstellung und Verwendung merge, join von dplyr, cbind, cbind.fill, aber alle eine solche, die entweder zurückgeben einzelne Spalte oder stimmen nicht Werte über alle Zeilen überein.

Was ist der beste Weg, um dieses Ergebnis mit R zu erhalten?

Antwort

5

A Base R Lösung:

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 

Ergebnis:

> 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 

oder mit 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)) 

Daten:

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

Fügen Sie einfach '[-1]' am Ende Ihrer Funktion. – Masoud

+0

@Masoud Danke, ich wollte klarstellen, was Reduce eigentlich macht – useR

5

Sie können unlist und unique verwenden, um alle möglichen Werte zu erhalten, und finden Sie dann ihre Übereinstimmungen über jeden der Vektoren. Wenn nichts passt, match kehrt NA wie Sie wollen:

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" 
Verwandte Themen