我有一串数字和一个清单:
a <- c(1,2,3)
b <- list( x<-c(1:5),y<-c(1:10),z<-c(10:20))
我想要做的是测试每个数字是否在列表的每个元素中 - 1是在x中,2是在y中,3是在z中。然后将1/0给一个新变量。
我的代码:
d <- ifelse(a %in% sapply(b,function(x) unlist(x)),1,0)
然而结果是:
> d
[1] 0 0 0
理想的结果应该是:
[1] 1 1 0
我该怎么做?谢谢
答案 0 :(得分:9)
您正在循环使用两组匹配的数据,这表示Map/mapply
:
mapply(`%in%`, a, b)
#[1] TRUE TRUE FALSE
as.integer(mapply(`%in%`, a, b))
#[1] 1 1 0
答案 1 :(得分:2)
值得注意的是is.element
相当于%in%
,因此您可以避免键入一些引号。如果您喜欢purrr
,可以使用
map2_int(a,b, is.element)
[1] 1 1 0
答案 2 :(得分:2)
purrr
包在*apply
系列和辅助函数上有许多变体,可用于处理列表。在这种情况下,它看起来像
library(purrr)
map2_int(a, b, ~.x %in% .y) # shorthand for map2_int(a, b, function(x, y){x %in% y})
## [1] 1 1 0
或
map2_int(a, b, `%in%`)
## [1] 1 1 0
其中
map
部分是将函数应用于列表元素的一组函数的名称,2
部分是一个版本,它将两个列表作为输入并且并行迭代它们,并且_int
部分是将结果简化为整数向量的版本。答案 3 :(得分:1)
使用for loop
函数模拟apply
的最佳方法是实际定义迭代器。
sapply(1:length(b), function(i) a[i] %in% b[[i]])
这将返回布尔值
[1] TRUE TRUE FALSE
使用as.integer()
我觉得这比mapply
更直观,并且通过自定义函数调用,您可以调整它,比如说if
语句搜索NA
列表。