Adrian
Adrian

Reputation: 9793

R: how to reverse order of sublists in a nested list

mylist <- list(list(structure(list(output = c(0.367578048046026, 0.605182475742302
), param_a = c(0, 0), param_b = c(0, 0)), row.names = c("result.1", 
"result.2"), class = "data.frame"), structure(list(output = c(0.548191163091365, 
0.592775921800048), param_a = c(0, 0), param_b = c(1, 1)), row.names = c("result.1", 
"result.2"), class = "data.frame"), structure(list(output = c(0.55779557429407, 
0.426207452622594), param_a = c(0, 0), param_b = c(2, 2)), row.names = c("result.1", 
"result.2"), class = "data.frame")), list(structure(list(output = c(1.07245641560775, 
1.16064672057236), param_a = c(1, 1), param_b = c(0, 0)), row.names = c("result.1", 
"result.2"), class = "data.frame"), structure(list(output = c(0.706195873854826, 
0.594066321995285), param_a = c(1, 1), param_b = c(1, 1)), row.names = c("result.1", 
"result.2"), class = "data.frame"), structure(list(output = c(1.48232534931638, 
0.674931223103637), param_a = c(1, 1), param_b = c(2, 2)), row.names = c("result.1", 
"result.2"), class = "data.frame")), list(structure(list(output = c(3.14408544130271, 
1.0665438146771), param_a = c(2, 2), param_b = c(0, 0)), row.names = c("result.1", 
"result.2"), class = "data.frame"), structure(list(output = c(1.20012816838846, 
1.27792564599787), param_a = c(2, 2), param_b = c(1, 1)), row.names = c("result.1", 
"result.2"), class = "data.frame"), structure(list(output = c(2.15408506667139, 
2.3394066423446), param_a = c(2, 2), param_b = c(2, 2)), row.names = c("result.1", 
"result.2"), class = "data.frame")))

I have a nested list that looks like this:

> mylist
[[1]]
[[1]][[1]]
            output param_a param_b
result.1 0.3675780       0       0
result.2 0.6051825       0       0

[[1]][[2]]
            output param_a param_b
result.1 0.5481912       0       1
result.2 0.5927759       0       1

[[1]][[3]]
            output param_a param_b
result.1 0.5577956       0       2
result.2 0.4262075       0       2


[[2]]
[[2]][[1]]
           output param_a param_b
result.1 1.072456       1       0
result.2 1.160647       1       0

[[2]][[2]]
            output param_a param_b
result.1 0.7061959       1       1
result.2 0.5940663       1       1

[[2]][[3]]
            output param_a param_b
result.1 1.4823253       1       2
result.2 0.6749312       1       2


[[3]]
[[3]][[1]]
           output param_a param_b
result.1 3.144085       2       0
result.2 1.066544       2       0

[[3]][[2]]
           output param_a param_b
result.1 1.200128       2       1
result.2 1.277926       2       1

[[3]][[3]]
           output param_a param_b
result.1 2.154085       2       2
result.2 2.339407       2       2

It has 3 outer sublists that correspond to param_a = 0, 1 or 2. It also has 3 inner sublists that correspond to param_b = 0, 1 or 2.

I would like to reverse the order of these lists so that the outer 3 sublists correspond to param_b and the inner ones correspond to param_a. In other words, I would like something that looks like this:

> mylist
[[1]]
[[1]][[1]]
            output param_a param_b
result.1 0.3675780       0       0
result.2 0.6051825       0       0

[[1]][[2]]
            output param_a param_b
result.1  1.072456       1       0
result.2  1.160647       1       0

[[1]][[3]]
            output param_a param_b
result.1  3.144085       2       0
result.2  1.066544       2       0


[[2]]
[[2]][[1]]
           output param_a param_b
result.1 0.5481912      0       1
result.2 0.5927759      0       1

[[2]][[2]]
            output param_a param_b
result.1 0.7061959       1       1
result.2 0.5940663       1       1

[[2]][[3]]
            output param_a param_b
result.1  1.200128       2       1
result.2  1.200128       2       1


[[3]]
[[3]][[1]]
            output param_a param_b
result.1 0.5577956       0       2
result.2 0.5577956       0       2

[[3]][[2]]
            output param_a param_b
result.1 1.4823253       1       2
result.2 0.6749312       1       2

[[3]][[3]]
           output param_a param_b
result.1 2.154085       2       2
result.2 2.339407       2       2

Is there a way of doing this in R?

Upvotes: 0

Views: 224

Answers (2)

s_baldur
s_baldur

Reputation: 33498

Using just base R:

n <- length(mylist)
m <- length(mylist[[1]]) # assume all are equal
newlist <- vector(mode='list', length = m)
for (i in 1:n)
  for (j in 1:m)
    newlist[[j]][[i]] <- mylist[[i]][[j]]

Upvotes: 0

G. Grothendieck
G. Grothendieck

Reputation: 269471

Use transpose from purrr

library(purrr)
transpose(mylist)

giving

[[1]]
[[1]][[1]]
            output param_a param_b
result.1 0.3675780       0       0
result.2 0.6051825       0       0

[[1]][[2]]
           output param_a param_b
result.1 1.072456       1       0
result.2 1.160647       1       0

[[1]][[3]]
           output param_a param_b
result.1 3.144085       2       0
result.2 1.066544       2       0


[[2]]
[[2]][[1]]
            output param_a param_b
result.1 0.5481912       0       1
result.2 0.5927759       0       1

[[2]][[2]]
            output param_a param_b
result.1 0.7061959       1       1
result.2 0.5940663       1       1

[[2]][[3]]
           output param_a param_b
result.1 1.200128       2       1
result.2 1.277926       2       1


[[3]]
[[3]][[1]]
            output param_a param_b
result.1 0.5577956       0       2
result.2 0.4262075       0       2

[[3]][[2]]
            output param_a param_b
result.1 1.4823253       1       2
result.2 0.6749312       1       2

[[3]][[3]]
           output param_a param_b
result.1 2.154085       2       2
result.2 2.339407       2       2

Upvotes: 2

Related Questions