简体   繁体   中英

Combining vectors in a subset of list of lists

I'd like to get a matrix mat out by combining vectors in a subset of list of lists. Following the way to do the same using a for loop. I am wondering if there is a faster way to do it.

  i <- 1 # the subset
  mat<- matrix(NA, ncol = p, nrow = n)
  for (j in 1 : p) {
    mat[, j] <- list_of_list[[j]][[i]]$the_vector
  }

EDIT: I am after the vectors indexed/subseted by 'i' at any given time. Also, the list_of_list has objects other than the_vector as well.

EDIT 2: Adding a working example below.

lst <- list()
list_of_list <- list()

lst[[1]] <- list(a="a", c="b1", the_vector = 1:5)
lst[[2]] <- list(a="b", c="b2", the_vector = 1:5+1)
lst[[3]] <- list(a="c", c="b3", the_vector = 1:5+2)
list_of_list[[1]] <- lst

lst[[1]] <- list(a="a", c="b1", the_vector = 1:5*0)
lst[[2]] <- list(a="b", c="b2", the_vector = 1:5*1)
lst[[3]] <- list(a="c", c="b3", the_vector = 1:5*22)
list_of_list[[2]] <- lst

i <- 1 # the subset
p <- 2 # length of the list of list
n <- 5 # length of the vector
mat<- matrix(NA, ncol = p, nrow = n)
for (j in 1 : p) {
  mat[, j] <- list_of_list[[j]][[i]]$the_vector
}

You can just unlist your list then reshape it as a matrix :

matrix(unlist(list(list(1,2,3,4),list(5,6,7,8),list(9,10,11,12))), nrow=3, byrow = T)
     [,1] [,2] [,3] [,4]
[1,]    1    2    3    4
[2,]    5    6    7    8
[3,]    9   10   11   12

You may try the sapply() function:

i <- 1L
mat <- sapply(list_of_list, function(.x) .x[[i]]$the_vector)
mat
  [,1] [,2] [1,] 1 0 [2,] 2 0 [3,] 3 0 [4,] 4 0 [5,] 5 0 

I have not benchmarked the code to make sure this is faster in terms of execution speed but it definitely requires fewer key strokes.

sapply() applies a function over a list or vector and is a kind of implied for loop.

I am not sure if you are looking for something like this. It will give you a list of 3 matrices corresponding to vector from list_of_list's child lists.

mapply(list_of_list[[1]],list_of_list[[2]],
FUN = function(x,y){t(mapply(x$the_vector,y$the_vector,
FUN = function(u,v){matrix(c(u,v),ncol=2,byrow = F,dimnames = NULL)},
SIMPLIFY = T))},SIMPLIFY = F)


#[[1]]
#     [,1] [,2]
#[1,]    1    0
#[2,]    2    0
#[3,]    3    0
#[4,]    4    0
#[5,]    5    0

#[[2]]
#     [,1] [,2]
#[1,]    2    1
#[2,]    3    2
#[3,]    4    3
#[4,]    5    4
#[5,]    6    5

#[[3]]
#     [,1] [,2]
#[1,]    3   22
#[2,]    4   44
#[3,]    5   66
#[4,]    6   88
#[5,]    7  110

Here is another solution really similar to @TUSHAr but that might maybe more modular:

## Lapply wrapping function that outputs a matrix
lapply.wrapper <- function(i, list_of_list) {
    matrix(unlist(lapply(list_of_list, function(X, i) X[[i]]$the_vector, i = i)), ncol = length(list_of_list))
}

## Using the wrapper on the first subset:
lapply.wrapper(1, list_of_list)

#     [,1] [,2]
#[1,]    1    0
#[2,]    2    0
#[3,]    3    0
#[4,]    4    0
#[5,]    5    0

## Applying the function to all subsets
sapply(1:length(list_of_list[[1]]), lapply.wrapper, list_of_list, simplify = FALSE)

#[[1]]
#     [,1] [,2]
#[1,]    1    0
#[2,]    2    0
#[3,]    3    0
#[4,]    4    0
#[5,]    5    0
#
#[[2]]
#     [,1] [,2]
#[1,]    2    1
#[2,]    3    2
#[3,]    4    3
#[4,]    5    4
#[5,]    6    5
#
#[[3]]
#     [,1] [,2]
#[1,]    3   22
#[2,]    4   44
#[3,]    5   66
#[4,]    6   88
#[5,]    7  110

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM