Reputation: 27
I have two list a and another sub list which is b:
a <- list(c("aa","bb","cc"), c("a","b","c","d","e"))
b <- list(c("aa","cc"),c("a","b","c"))
I'd like to extract b from a and result should looks like
list(c("bb"), c("d","e")
I have tried:
1) Map(`[`, a, b)
2) map2(a, b, `[`)
3) sapply(names(a), function(x) a[[x]][,b[[x]], drop = FALSE])
But non of them works. I appreciate your help and support.
Upvotes: 1
Views: 122
Reputation: 14764
Try:
Map(function(x, y) x[!x %in% y], a, b)
[[1]]
[1] "bb"
[[2]]
[1] "d" "e"
Upvotes: 0
Reputation: 887391
An option would be to use setdiff
with Map
Map(setdiff, a, b)
#[[1]]
#[1] "bb"
#[[2]]
#[1] "d" "e"
Or the similar option in map2
library(purrr)
map2(a, b, setdiff)
Regarding the use of names
to loop, if we check the names(a)
or names(b)
, it is NULL
names(a)
#NULL
because the names were not set. When creating the list
, it can be done with
a1 <- list(v1 = c("aa","bb","cc"), v2 = c("a","b","c","d","e"))
or after the list
is created. can set the names with
names(a1) <- c("v1", "v2")
or while creating the list, use setNames
a1 <- setNames(list(c("aa","bb","cc"), c("a","b","c","d","e")), c("v1", "v2"))
if the names
are NULL
, looping through NULL
will fail anyway. An option that is more better is to loop through the numeric index or sequence of list
. We don't have to worry about whether the names are set or not.
lapply(seq_along(a), function(i) setdiff(a[[i]], b[[i]]))
Upvotes: 2