比较R中的两个列表

Asl*_*986 54 r venn-diagram

我有两个ID列表.

我想比较两个列表,特别是我对以下数据感兴趣:

  • 列表A和B中有多少个ID
  • A中有多少个ID,但B中没有
  • B中有多少个ID,但A中没有

我也想画一个维恩图.

Mit*_*ops 76

以下是一些尝试的基础知识:

> 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" 
Run Code Online (Sandbox Code Playgroud)

同样,您可以简单地将计数视为:

> length(intersect(A,B))
[1] 1
> length(setdiff(A,B))
[1] 2
> length(setdiff(B,A))
[1] 2
Run Code Online (Sandbox Code Playgroud)


Fra*_*ank 20

我通常处理大型集合,所以我使用表而不是维恩图:

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
Run Code Online (Sandbox Code Playgroud)


Tee*_*ala 13

另一种方式,使用%in%和公共元素的布尔向量而不是intersectsetdiff.我认为你实际上想要比较两个向量,而不是两个列表 - 列表是一个R类,可以包含任何类型的元素,而向量总是包含只有一种类型的元素,因此更容易比较真正相等的东西.这里元素被转换为字符串,因为这是存在的最不灵活的元素类型.

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))
Run Code Online (Sandbox Code Playgroud)

就像它提到的那样,在R中绘制维恩图有多种选择.这是使用gplots的输出.

与gplots的维恩图