How to use cbind on matrices in one list and place

2019-08-20 23:00发布

问题:

I'm trying to join matrices stored in nested lists and place them in a new list. For example, if I have a list of fruit, I would like to take various matrices stored under Kiwi, and join them together as one matrix in a new list.

This will generate something that looks like my data:

#Define some important things
Fruits = c('Mango', 'Kiwi')
Attr = c('Size', 'Shape')

#generate empty lists
MyFruitList <- lapply(Fruits, function(q) {
  EmptySublist <- (setNames(vector("list", length(Fruits)), Attr))
})
names(MyFruitList) <- Fruits

#Full lists with example matrices
MyFruitList[['Mango']][['Size']] <- matrix(c(3,5,7,2), nrow=2, ncol=2)
MyFruitList[['Mango']][['Shape']] <- matrix(c(3,6,7,5), nrow=2, ncol=2)

MyFruitList[['Kiwi']][['Size']] <- matrix(c(1,3,4,2), nrow=2, ncol=2)
MyFruitList[['Kiwi']][['Shape']] <- matrix(c(2,4,5,1), nrow=2, ncol=2)

And here is what I have been trying to use to move the matrices stored under Kiwi and Mango into a new list.

#Obviously this doesn't actually work
MyFruitListAsRows <- lapply(Fruits, function(i) {
  MyFruitListAsRows <- matrix(cbind(paste0(MyFruitList[i]))) 
})
names(MyFruitListAsRows) <- paste0(Fruits, "Row")

Ideally I should end up with a list called MyFruitsAsRows which contains 2, 4 by 2 matrices named Kiwi and Mango, containing their respective Size and Shape data from the original MyFruitList list.

e.g. For Mango it would look like this:

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

(Sorry that the numbers are overly similar, that was not well planned and might make it hard at first to recognise where I'd like my numbers to go)

Having been constructed from this:

$Size
     [,1] [,2]
[1,]    3    7
[2,]    5    2

$Shape
     [,1] [,2]
[1,]    3    7
[2,]    6    5

Edit: I have tried to adapt the advice of Ronak Shah and done the following:

library(tidyverse)

MyFruitListAsRows <- map(MyFruitList[i], bind_cols)

but running either,

MyFruitListAsRows[['KiwiRow']]
MyFruitListAsRows[['MangoRow']]

Produces:

I get Error in x[i, , drop = FALSE] : subscript out of bounds

If I try to get RStudio to show me what's in either of my new lists in a window, RStudio encounters a fatal error and crashes.

回答1:

We can use base R to loop over each MyFruitList and cbind them with do.call

lapply(MyFruitList, function(x) do.call(cbind, x))

#$Mango
#     [,1] [,2] [,3] [,4]
#[1,]    3    7    3    7
#[2,]    5    2    6    5

#$Kiwi
#     [,1] [,2] [,3] [,4]
#[1,]    1    4    2    5
#[2,]    3    2    4    1

You can also use cbind.data.frame here.


Using tidyverse we can map over each list and then cbind

library(tidyverse)
map(MyFruitList, cbind.data.frame)

#$Mango
#  Size.1 Size.2 Shape.1 Shape.2
#1      3      7       3       7
#2      5      2       6       5

#$Kiwi
#  Size.1 Size.2 Shape.1 Shape.2
#1      1      4       2       5
#2      3      2       4       1