%in%很简单
本文是对全国巡讲的补充,但也写全了背景知识,可以从头学习。
1.背景知识
上课时讲到【向量取子集】的两种方法:
(1)根据逻辑值
x <- 8:12
x[x==10]
#> [1] 10
x[x<12]
#> [1] 8 9 10 11
x[x %in% c(9,13)]
#> [1] 9
(2)根据位置取子集
x[4]
#> [1] 11
x[2:4]
#> [1] 9 10 11
x[c(1,5)]
#> [1] 8 12
x[-4]
#> [1] 8 9 10 12
x[-(2:4)]
#> [1] 8 12
2.关于%in%的答疑
按照逻辑值取子集,"[ ]"内应该是一个与变量等长的逻辑值向量,按照位置取,"[ ]"内则应该是表示元素位置的数值型向量。
%in%
这个符号对大多数人来说比较陌生,x %in% y
的意思是“对x里的每个元素进行判断,判断它是否在y中存在,存在就返回TRUE,不存在就返回FALSE”。
注意,它的返回值与其他符号一样,是一个与x等长的逻辑值向量。
例题及答案
我们现在有12个基因名,要从其中挑出指定的3个。
12个基因名是:"ACTR3B","ANLN","BAG1","BCL2","BIRC5","RAB","ABCT","ANF","BAD","BCF","BARC7","BALV"
3个基因名是: "ANLN", "BCL2","TP53"
答案很简单:
x = c("ACTR3B","ANLN","BAG1","BCL2","BIRC5","RAB","ABCT","ANF","BAD","BCF","BARC7","BALV")
y = c("ANLN", "BCL2","TP53")
x[x %in% y]
#> [1] "ANLN" "BCL2"
问题1
x %in% y
,如何确定两个向量谁在前、谁在后?
需要确定的是,你的操作对象谁,对谁进行判断?
根据题目,是对12个进行判断。所以它在前,返回的逻辑值向量长度为12,才可以将这个向量放入[ ]中,对x取子集,将对应结果为TRUE的留下,而FALSE 丢掉。
x %in% y
#> [1] FALSE TRUE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
#> [12] FALSE
length(x %in% y)
#> [1] 12
x[x %in% y]
#> [1] "ANLN" "BCL2"
问题2
两个向量是否可以颠倒?
不一定,根据实际情况决定。
刚才的例子,xy颠倒虽然逻辑不和题目一直,但是结果市没有差别的。
x[x %in% y]
#> [1] "ANLN" "BCL2"
y[y %in% x]
#> [1] "ANLN" "BCL2"
举一个特例,其中一个向量存在重复值的情况:
x = c("ACTR3B","ANLN","ANLN","BCL2","BIRC5","RAB","ABCT","ANF","BAD","BCF","BARC7","BALV")
y = c("ANLN", "BCL2","TP53")
x[x %in% y]
#> [1] "ANLN" "ANLN" "BCL2"
y[y %in% x]
#> [1] "ANLN" "BCL2"
可以看到,返回的结果是不一样的!再次理解下这句话:“对x里的每个元素进行判断,判断它是否在y中存在,存在就返回TRUE,不存在就返回FALSE”。
问题3
x[ x %in% y]
,可以写成 y[x %in% y]
吗?
不可以,因为"[]"里的逻辑值向量要求和x长度一致,而 y %in% x
返回的向量是与y的长度一致,逻辑是错的。
y[x %in% y]
#> [1] "BCL2" "TP53" NA
问题4
%in% 和intersect 有区别吗?
和第二题一样,不一定。存在重复值的时候就不一样了。
x = c("ACTR3B","ANLN","ANLN","BCL2","BIRC5","RAB","ABCT","ANF","BAD","BCF","BARC7","BALV")
y = c("ANLN", "BCL2","TP53")
intersect(x,y)
#> [1] "ANLN" "BCL2"