J. Krämer
J. Krämer

Reputation: 13

Access vectors in a list with an array of indices in R

I have a list containing 3 vectors, e.g.:

> test_list
[[1]]
[1] "a" "b"

[[2]]
[1] "c" "d" "e"

[[3]]
[1] "f" "g"

I want to access elements of those vectors using an array containing the vector indices, e.g.:

> indices
     [,1] [,2] [,3]
[1,]    1    3    2
[2,]    2    2    2

This is the desired output:

     [,1] [,2] [,3]
[1,] "a"  "e"  "g"
[2,] "b"  "d"  "g"

I found the following way to do it:

test_list <- list(c("a", "b"), c("c", "d", "e"), c("f", "g"))
indices <- matrix(c(1, 3, 2, 2, 2, 2), nrow = 2, ncol = 3, byrow = TRUE)
t(apply(indices, 1, function(row){mapply(`[[`, test_list, row)}))

Is there a cleaner, more idiomatic way?

Upvotes: 1

Views: 574

Answers (2)

akrun
akrun

Reputation: 887911

Another option in base R

out <- do.call(rbind, lapply(test_list, `length<-`, max(lengths(test_list))))   
`dim<-`(out[cbind(c(col(indices)), c(indices))], c(2,  3))
#    [,1] [,2] [,3]
#[1,] "a"  "e"  "g" 
#[2,] "b"  "d"  "g" 

Upvotes: 2

tmfmnk
tmfmnk

Reputation: 40171

One option involving purrr could be:

map2(.x = test_list, 
     .y = asplit(indices, 2),
     ~ .x[.y]) %>%
 transpose()

[[1]]
[1] "a" "e" "g"

[[2]]
[1] "b" "d" "g"

Or a base R solution using the idea from the comment provided by @nicola:

mapply(`[`, test_list, asplit(indices, 2))

Upvotes: 3

Related Questions