I have already asked this question but wasn't well presented, so I decided to ask again from scratch.
I have a Large List object in R containing 100 lists of outputs of different models, each output is itself a list containing the statistics for all the parameters of the model. So I have a sublist for the means, one for sd, etc, inside each one of the 100 outputs lists. Each statistics have a vector or matrix for each parameter of the model. What I want is to merge all the 100 lists outputs in one single large list by aggregating them based on their statistics and parameters names.
modeloutputs <- list("model1"=list("simlist"=list("N"=c(1,2,3,4,5,6,7), "sigma"=c(1,2,3,4), "theta"=c(7,8,9)),
"sd" = list("N"=c(6), "sigma"=c(6.5), "theta"=matrix(6:11, nrow = 2, ncol = 3)),
"mean" = list("N"=c(3), "sigma"=c(3.5), "theta"=matrix(6:11, nrow = 2, ncol = 3))),
"model2"=list("simlist"=list("N"=c(8,9,10,11,12,13,14), "sigma"=c(1,2,3,4), "theta"=c(7,8,9)),
"sd" = list("N"=c(7), "sigma"=c(8.5), "theta"=matrix(6:11, nrow = 2, ncol = 3)),
"mean" = list("N"=c(5), "sigma"=c(5.5), "theta"=matrix(6:11, nrow = 2, ncol = 3))),
"model3"=list("simlist"=list("N"=c(15,16,17,18,19,20,21), "sigma"=c(1,2,3,4), "theta"=c(7,8,9)),
"sd" = list("N"=c(8), "sigma"=c(8.5), "theta"=matrix(6:11, nrow = 2, ncol = 3)),
"mean" = list("N"=c(9), "sigma"=c(9.5), "theta"=matrix(6:11, nrow = 2, ncol = 3))))
modeloutputs_wanted <- list("allmodels"=list("simlist"=list("N"=c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21), "sigma"=c(1,2,3,4,1,2,3,4,1,2,3,4), "theta"=c(7,8,9,7,8,9,7,8,9)),
"sd" = list("N"=c(6,7,8), "sigma"=c(6.5,8.5,8.5), "theta"=matrix(6:11, nrow = 2, ncol = 3)),
"mean" = list("N"=c(3,5,9), "sigma"=c(3.5,5.5,9.5), "theta"=matrix(6:11, nrow = 2, ncol = 3))))
theta should have all the matrixes concatenated by row like a rowbind(), I wasn't able to reproduce it correctly in the example.
CodePudding user response:
This is close to what you're looking for:
library(purrr)
transpose(modeloutputs) |>
map(~ transpose(.x)) %>%
map_depth(2, ~ if(all(sapply(.x, is.matrix))) unique(.x) else reduce(.x, c))
output
$simlist
$simlist$N
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
[21] 21
$simlist$sigma
[1] 1 2 3 4 1 2 3 4 1 2 3 4
$simlist$theta
[1] 7 8 9 7 8 9 7 8 9
$sd
$sd$N
[1] 6 7 8
$sd$sigma
[1] 6.5 8.5 8.5
$sd$theta
$sd$theta[[1]]
[,1] [,2] [,3]
[1,] 6 8 10
[2,] 7 9 11
$mean
$mean$N
[1] 3 5 9
$mean$sigma
[1] 3.5 5.5 9.5
$mean$theta
$mean$theta[[1]]
[,1] [,2] [,3]
[1,] 6 8 10
[2,] 7 9 11
CodePudding user response:
or in base R:
agg_list <- list()
for(statistic in lapply(modeloutputs, names)[[1]]){
theta_vec<- c()
theta <- matrix(ncol=3)
N_vec<- c()
sigma_vec<- c()
for(model in names(modeloutputs)){
if(statistic == "simlist"){
theta_vec <- c(theta_vec, modeloutputs[[model]][[statistic]][["theta"]])
sigma_vec <- c(sigma_vec, modeloutputs[[model]][[statistic]][["sigma"]])
N_vec <- c(N_vec, modeloutputs[[model]][[statistic]][["N"]])
stats <-list("N"=N_vec, "sigma"=sigma_vec, "theta"=theta_vec )
}else{
theta <- rbind(theta, modeloutputs[[model]][[statistic]][["theta"]])
theta <- na.omit(theta)
sigma_vec <- c(sigma_vec, modeloutputs[[model]][[statistic]][["sigma"]])
N_vec <- c(N_vec, modeloutputs[[model]][[statistic]][["N"]])
stats <- list("N"=N_vec, "sigma"=sigma_vec, "theta"=theta )
}
}
agg_list <- append(agg_list , list(stats))
}
names(agg_list) <- sapply(modeloutputs, names)[,1]
But admittedly the answer by @Maël is much more elegant :)