I have a list of numeric vectors:
a <- list(c(2, 3, 4, 5, 6, 7), c(4, 5, 6, 7, 8), c(6, 7, 8, 9, 10))
> a
[[1]]
[1] 2 3 4 5 6 7
[[2]]
[1] 4 5 6 7 8
[[3]]
[1] 6 7 8 9 10
I want to create a list where each element corresponds to values from 1 to the max value in the original list "a". The values in each element of the new list are the indices in the original list containing the focal value.
For example, the first element in the result contains the indices in "a" with the value 1. Because no element contains 1, the result is NULL
. The second element contains the indices in "a" with the value 2, i.e. the first element, 1. The value 4 is found in element 1 and 2.
> res
[[1]]
NULL
[[2]]
[1] 1
[[3]]
[1] 1
[[4]]
[2] 1 2
[[5]]
[2] 1 2
[[6]]
[3] 1 2 3
[[7]]
[3] 1 2 3
[[8]]
[2] 2 3
[[9]]
[1] 3
[[10]]
[1] 3
I tried this with nested loops, but it is taking too much time and growing lists within loops is very slow. I have 60,000 sublists in my main list, so is there vectorized solution for this ?
Thanks in Advance.
CodePudding user response:
Here is a base R way.
lapply(seq.int(max(unique(unlist(a)))), \(i){
which(sapply(a, \(x) any(i == x)))
})
CodePudding user response:
Another way:
searchInList <- function(list2search, e){
idx2search <- 1:length(list2search)
list2search2 <- lapply(list2search, `length<-`, max(lengths(list2search)))
output <- matrix(unlist(list2search2), ncol = length(list2search2[[1]]), byrow = TRUE)
idx <- apply(output, 1, function(x){ (e %in% x) } )
return(idx2search[idx])
}
result <- lapply(1:max(unlist(a)), function(x) { searchInList(a, x) } )
CodePudding user response:
Here is one way using match
and rapply
.
apply(matrix(rapply(a, \(x) !is.na(match(1:max(unlist(a)), x))),,length(a)), 1, which)
# [[1]]
# integer(0)
#
# [[2]]
# [1] 1
#
# [[3]]
# [1] 1
#
# [[4]]
# [1] 1 2
#
# [[5]]
# [1] 1 2
#
# [[6]]
# [1] 1 2 3
#
# [[7]]
# [1] 1 2 3
#
# [[8]]
# [1] 2 3
#
# [[9]]
# [1] 3
#
# [[10]]
# [1] 3
CodePudding user response:
Another solution using base R:
apply(sapply(a, `%in%`, x = seq_len(max(unlist(a)))), 1, which)