Toby Muhlhofer
Toby Muhlhofer

Reputation: 95

Processing list object

I have a list object in R that contains further lists, of three vectors each. What is the quickest way to generate three matrices, the first of which has all of the first vectors as rows, the second has all of the second vectors as rows, and the third has all of the third? For example, given:

metalist <- list(list(c(1,1),c(11,11),c("a","a")),
                 list(c(2,2),c(22,22),c("b","b")),
                 list(c(3,3),c(33,33),c("c","c")))

I would like to get to three matrices (or data.frames), the first consisting of:

1 1

2 2

3 3

The second consisting of

11 11

22 22

33 33

And the third consisting of

a a

b b

c c

Given that in reality the metalist has 50,000 list objects, a for loop that extracts the vector elements and progressively assembles the matrices takes forever, so I would be looking for something quicker. I'm guessing there may be some clever use of unlist() but I can't figure it out.

Upvotes: 4

Views: 207

Answers (3)

A. Webb
A. Webb

Reputation: 26446

The pattern do.call(Map,c(f=___,...)) is a useful one to have in your toolbox. Using list in the blank "transposes" the structure, using rbind will produce your desired matrices:

do.call(Map,c(f=rbind,metalist))

[[1]]
     [,1] [,2]
[1,]    1    1
[2,]    2    2
[3,]    3    3

[[2]]
     [,1] [,2]
[1,]   11   11
[2,]   22   22
[3,]   33   33

[[3]]
     [,1] [,2]
[1,] "a"  "a" 
[2,] "b"  "b" 
[3,] "c"  "c" 

Upvotes: 1

Zslice
Zslice

Reputation: 412

If you would like to completely ignore for loops, the following also gets the job done:

lapply(1:3, function(y) {
do.call(rbind,lapply(metalist, function(x) x[[y]]))
})

Upvotes: 0

lish
lish

Reputation: 192

The following will create a list of three matrices:

my_outcome <- list()
for (i in 1:3)
{
    my_outcome[[i]] <- t(as.data.frame(lapply(metalist, `[[`, i)))
}

It does use a loop, but only over the number of matrices, so it should work in your case.

Upvotes: 0

Related Questions