2013-07-11 22 views
38

Mam dwie listy identyfikatorów.Porównaj dwie listy w R

chciałbym porównać dwie listy, w szczególności jestem zainteresowany w następujących liczbach:

  • Ile Identyfikatory są zarówno w wykazie A i B
  • Ile identyfikatory są w A, ale nie w B
  • Ile identyfikatory są w B, ale nie w

Chciałbym również miłość do rysowania diagramu Venna.

+6

zobacz '?? intersect' i' ?? setdiff' ... – agstudy

+1

patrz [diagramów Venna z R?] (http://stackoverflow.com/q/1428946/59470) – topchef

+2

ISN” t to jest nieprawidłowe użycie terminu "lista" w R? To tylko dwa wektory. To zupełnie nie to samo. – emilBeBri

Odpowiedz

58

Oto pewne podstawy do wypróbowania:

> A = c("Dog", "Cat", "Mouse") 
> B = c("Tiger","Lion","Cat") 
> A %in% B 
[1] FALSE TRUE FALSE 
> intersect(A,B) 
[1] "Cat" 
> setdiff(A,B) 
[1] "Dog" "Mouse" 
> setdiff(B,A) 
[1] "Tiger" "Lion" 

Podobnie, można uzyskać liczy po prostu jako:

> length(intersect(A,B)) 
[1] 1 
> length(setdiff(A,B)) 
[1] 2 
> length(setdiff(B,A)) 
[1] 2 
11

Jeszcze inny inny sposób, z użyciem % w% i logicznych wektorów wspólnych elementów zamiast przecinają się i setdiff. Rozumiem, że faktycznie chcesz porównać dwa wektory , a nie dwie list - a lista jest klasą R, która może zawierać dowolny typ elementu, podczas gdy wektory zawsze zawierają elementy tylko jednego typu, a więc łatwiejsze porównanie jest naprawdę równy. Tutaj elementy są przekształcane na ciągi znaków, ponieważ był to najbardziej nieelastyczny typ elementu, który był obecny.

first <- c(1:3, letters[1:6], "foo", "bar") 
second <- c(2:4, letters[5:8], "bar", "asd") 

both <- first[first %in% second] # in both, same as call: intersect(first, second) 
onlyfirst <- first[!first %in% second] # only in 'first', same as: setdiff(first, second) 
onlysecond <- second[!second %in% first] # only in 'second', same as: setdiff(second, first) 
length(both) 
length(onlyfirst) 
length(onlysecond) 

#> both 
#[1] "2" "3" "e" "f" "bar" 
#> onlyfirst 
#[1] "1" "a" "b" "c" "d" "foo" 
#> onlysecond 
#[1] "4" "g" "h" "asd" 
#> length(both) 
#[1] 5 
#> length(onlyfirst) 
#[1] 6 
#> length(onlysecond) 
#[1] 4 

# If you don't have the 'gplots' package, type: install.packages("gplots") 
require("gplots") 
venn(list(first.vector = first, second.vector = second)) 

Tak jak wspomniano, istnieje wiele opcji do kreślenia diagramów Venna w R. Oto dane wyjściowe za pomocą gplots.

venn diagram with gplots

16

jestem zwykle do czynienia z dużymi zestawami-owski, więc używam tabeli zamiast diagramu Venna:

xtab_set <- function(A,B){ 
    both <- union(A,B) 
    inA  <- both %in% A 
    inB  <- both %in% B 
    return(table(inA,inB)) 
} 

set.seed(1) 
A <- sample(letters[1:20],10,replace=TRUE) 
B <- sample(letters[1:20],10,replace=TRUE) 
xtab_set(A,B) 

#  inB 
# inA  FALSE TRUE 
# FALSE  0 5 
# TRUE  6 3 
+0

Ah, nie zdawałem sobie sprawy, że diagramy Venna zawierają liczby ... Myślałem, że powinny same pokazać przedmioty. – Frank

4

Z sqldf: Wolniej, ale bardzo nadaje się do ramek danych z mieszanych rodzaje:

t1 <- as.data.frame(1:10) 
t2 <- as.data.frame(5:15) 
sqldf1 <- sqldf('SELECT * FROM t1 EXCEPT SELECT * FROM t2') # subset from t1 not in t2 
sqldf2 <- sqldf('SELECT * FROM t2 EXCEPT SELECT * FROM t1') # subset from t2 not in t1 
sqldf3 <- sqldf('SELECT * FROM t1 UNION SELECT * FROM t2') # UNION t1 and t2 

sqldf1 X1_10 
1 
2 
3 
4 
sqldf2 X5_15 
11 
12 
13 
14 
15 
sqldf3 X1_10 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13  
14 
15