Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transpose a List of Lists

Tags:

r

I have a list which contains list entries, and I need to transpose the structure. The original structure is rectangular, but the names in the sub-lists do not match.

Here is an example:

ax <- data.frame(a=1,x=2)
ay <- data.frame(a=3,y=4)
bw <- data.frame(b=5,w=6)
bz <- data.frame(b=7,z=8)
before <- list(  a=list(x=ax, y=ay),   b=list(w=bw, z=bz))

What I want:

after  <- list(w.x=list(a=ax, b=bw), y.z=list(a=ay, b=bz))

I do not care about the names of the resultant list (at any level).

Clearly this can be done explicitly:

after <- list(x.w=list(a=before$a$x, b=before$b$w), y.z=list(a=before$a$y, b=before$b$z))

but this is ugly and only works for a 2x2 structure. What's the idiomatic way of doing this?

like image 517
Matthew Lundberg Avatar asked Apr 23 '13 21:04

Matthew Lundberg


People also ask

How do you transpose a list of lists in Python?

You can transpose a two-dimensional list using the built-in function zip() . zip() is a function that returns an iterator that summarizes the multiple iterables ( list , tuple , etc.). In addition, use * that allows you to unpack the list and pass its elements to the function.

Can you have a list of list of lists in Python?

Python provides an option of creating a list within a list. If put simply, it is a nested list but with one or more lists inside as an element. Here, [a,b], [c,d], and [e,f] are separate lists which are passed as elements to make a new list. This is a list of lists.

How do I transpose a list in R?

Rotating or transposing R objects You can rotate the data. frame so that the rows become the columns and the columns become the rows. That is, you transpose the rows and columns. You simply use the t() command.


2 Answers

The following piece of code will create a list with i-th element of every list in before:

lapply(before, "[[", i)

Now you just have to do

n <- length(before[[1]]) # assuming all lists in before have the same length
lapply(1:n, function(i) lapply(before, "[[", i))

and it should give you what you want. It's not very efficient (travels every list many times), and you can probably make it more efficient by keeping pointers to current list elements, so please decide whether this is good enough for you.

like image 127
Victor K. Avatar answered Oct 13 '22 16:10

Victor K.


The purrr package now makes this process really easy:

library(purrr)

before %>% transpose()

## $x
## $x$a
##   a x
## 1 1 2
## 
## $x$b
##   b w
## 1 5 6
## 
## 
## $y
## $y$a
##   a y
## 1 3 4
## 
## $y$b
##   b z
## 1 7 8
like image 42
alistaire Avatar answered Oct 13 '22 18:10

alistaire