Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unlist list of lists that have matrix elements to a list of matrices

Tags:

r

Suppose that A, B and C are matrices. And I have a list of them like this:

  list(A,list(B,C))

I want to convert it to this:

  list(A,B,C)

The unlist function convert the matrices to vectors!

For example:

A=matrix(1:10,nrow=2)
B=list(A,list(A,A))
unlist(B)
like image 219
user1436187 Avatar asked Jul 11 '15 15:07

user1436187


People also ask

How do I unlist a matrix in R?

To convert R List to Matrix, use the matrix() function and pass the unlist(list) as an argument. The unlist() method in R simplifies it to produce a vector that contains all the atomic components which occur in list data.

Can you have a list of matrices in Python?

You can add lists as matrices in Python.

Can a list contain a list in R?

The list is one of the most versatile data types in R thanks to its ability to accommodate heterogenous elements. A single list can contain multiple elements, regardless of their types or whether these elements contain further nested data. So you can have a list of a list of a list of a list of a list …


2 Answers

Here is a recursive implementation:

flatten2 <- function(X) if(is.list(X)) Reduce(c, lapply(X, flatten2)) else list(X)

Then:

str(flatten2(B))   # list of three matrices:
# List of 3
#  $ : int [1:2, 1:5] 1 2 3 4 5 6 7 8 9 10
#  $ : int [1:2, 1:5] 1 2 3 4 5 6 7 8 9 10
#  $ : int [1:2, 1:5] 1 2 3 4 5 6 7 8 9 10

And more complex:

C <- list(A, list(list(A, A), A))
str(flatten2(C))
# List of 4
#  $ : int [1:2, 1:5] 1 2 3 4 5 6 7 8 9 10
#  $ : int [1:2, 1:5] 1 2 3 4 5 6 7 8 9 10
#  $ : int [1:2, 1:5] 1 2 3 4 5 6 7 8 9 10
#  $ : int [1:2, 1:5] 1 2 3 4 5 6 7 8 9 10

Also, a "wordier" but faster version (this is the one tested by Pierre):

flatten <- function(X) {
  res <- list()
  for(i in X) res <- c(res, if(is.list(i)) Recall(i) else list(i))
  res
}

You could also make flatten2 a little faster by replacing Reduce with do.call, but that is a little less cute. flatten remains the fastest even with that change.

like image 86
BrodieG Avatar answered Sep 20 '22 18:09

BrodieG


You could do something like this

delist<-function(x) {
    lists <- sapply(x, class)=="list"
    while(any(lists)) {
        x<-mapply(function(y,z) if (!z) list(y) else (y), x, lists, SIMPLIFY=FALSE)
        x<-do.call('c', x)
        lists <- sapply(x, class)=="list"
    }
    x
}

with your example you get

delist(B)
# [[1]]
#      [,1] [,2] [,3] [,4] [,5]
# [1,]    1    3    5    7    9
# [2,]    2    4    6    8   10
# 
# [[2]]
#      [,1] [,2] [,3] [,4] [,5]
# [1,]    1    3    5    7    9
# [2,]    2    4    6    8   10
# 
# [[3]]
#      [,1] [,2] [,3] [,4] [,5]
# [1,]    1    3    5    7    9
# [2,]    2    4    6    8   10
like image 39
MrFlick Avatar answered Sep 21 '22 18:09

MrFlick