[英]Compare two character vectors in R
我有兩個 ID 的字符向量。
我想比較兩個字符向量,特別是我對以下數字感興趣:
我也很想畫一個維恩圖。
以下是一些可以嘗試的基礎知識:
> 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"
同樣,您可以簡單地獲得計數:
> length(intersect(A,B))
[1] 1
> length(setdiff(A,B))
[1] 2
> length(setdiff(B,A))
[1] 2
我通常處理大型集,所以我使用表格而不是維恩圖:
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
還有另一種方式,使用%in%和公共元素的布爾向量而不是intersect和setdiff 。 我認為您實際上想要比較兩個向量,而不是兩個列表-列表是一個 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))
就像前面提到的,在 R 中繪制維恩圖有多種選擇。這是使用 gplots 的輸出。
使用 sqldf:較慢但非常適合混合類型的數據幀:
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
使用與上述答案之一相同的示例數據。
A = c("Dog", "Cat", "Mouse")
B = c("Tiger","Lion","Cat")
match(A,B)
[1] NA 3 NA
該match
函數返回與該位置的矢量B
在所有值的A
。 所以, cat
是A
的第二個元素,是B
的第三個元素。 沒有其他比賽。
要獲取A
和B
的匹配值,您可以執行以下操作:
m <- match(A,B)
A[!is.na(m)]
"Cat"
B[m[!is.na(m)]]
"Cat"
要獲取A
和B
的不匹配值:
A[is.na(m)]
"Dog" "Mouse"
B[which(is.na(m))]
"Tiger" "Cat"
此外,您可以使用length()
來獲取匹配和不匹配值的總數。
如果A
是一個 data.table 字段a
的類型列表,條目本身作為一個基本類型的向量,例如創建如下
A<-data.table(a=c(list(c("abc","def","123")),list(c("ghi","zyx"))),d=c(9,8))
和B
是一個帶有原始條目向量的列表,例如創建如下
B<-list(c("ghi","zyx"))
並且您正在嘗試查找A$a
哪個(如果有)元素與B
匹配
A[sapply(a,identical,unlist(B))]
如果你只是想在進入a
A[sapply(a,identical,unlist(B)),a]
如果你想的匹配indicies a
A[,which(sapply(a,identical,unlist(B)))]
如果 B 本身是一個與 A 具有相同結構的 data.table,例如
B<-data.table(b=c(list(c("zyx","ghi")),list(c("abc","def",123))),z=c(5,7))
並且您正在尋找一列的兩個列表的交集,您需要相同順序的向量元素。
# give the entry in A for in which A$a matches B$b
A[,`:=`(res=unlist(sapply(list(a),function(x,y){
x %in% unlist(lapply(y,as.vector,mode="character"))
},list(B[,b]),simplify=FALSE)))
][res==TRUE
][,res:=NULL][]
# get T/F for each index of A
A[,sapply(list(a),function(x,y){
x %in% unlist(lapply(y,as.vector,mode="character"))
},list(B[,b]),simplify=FALSE)]
請注意,您不能做一些像
setkey(A,a)
setkey(B,b)
A[B]
加入 A&B 因為你不能在 data.table 1.12.2 中鍵入list
類型的字段
同樣,你不能問
A[a==B[,b]]
即使 A 和 B 相同,因為==
運算符尚未在 R 中實現用於類型list
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.