mccandar
mccandar

Reputation: 788

Merge multidimensional lists into one

I have a list like

[[1]]
NULL

[[2]]
NULL

[[3]]
     i index
[1,] 3  6359

(...)

[[7]]
NULL

[[8]]
     i index
[1,] 8  1609
[2,] 8  2197
[3,] 8  3045

[[9]]
     i index
[1,] 9  1342
[2,] 9  5831

[[10]]
NULL

and created with

  temp <- parSapply(cl,seq_along(source),function(i){ 
    index <- which(target[,col]==source[i])
    if(length(index)!=0)
      cbind(i,index)
  })

I want to turn this list into another list or data frame like

i index
3 6359
8 1609
8 2197
8 3045
9 1342
9 5831

in a way that I quickly get entire column with temp[[1]] or temp[,1] etc. It would be nice without rbind and with the fastest possible (parallel would be awesome) way.

Upvotes: 1

Views: 262

Answers (3)

OmaymaS
OmaymaS

Reputation: 1731

You can use purrr::map as follows:

I created a sample list dat :

# sample list
dat <- list(NULL,NULL,
            matrix(c(3,6359),nrow=1),
            matrix(c(9,9,1342,5831),nrow=2)
)

> dat
[[1]]
NULL

[[2]]
NULL

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

[[4]]
     [,1] [,2]
[1,]    9 1342
[2,]    9 5831

No you can do the following:

  • convert the matrices to dataframes

  • remove NULLs if you don't want NA in the results

  • use purrr::map to extract the values and create a new dataframe


# convert matrices to dataframes
dat <- sapply(dat,data.frame)

# remove NULL entries
dat <- dat[lengths(dat) > 0] # Don't use, if you wat to keep NAs

# use map to extract the values
res <- data.frame(i=map(dat,"X1", .null = NA) %>% unlist,
                  index=map(dat,"X2", .null = NA) %>% unlist)

And the results is:

> res
  i index
1 3  6359
2 9  1342
3 9  5831

Upvotes: 0

akrun
akrun

Reputation: 887301

We can do this with base R

do.call(rbind, lst)
#     i index
#[1,] 3  6359
#[2,] 8  1609
#[3,] 8  2197
#[4,] 8  3045
#[5,] 9  1392
#[6,] 9  5831

Or another option is rbindlist from data.table

library(data.table)
rbindlist(lapply(lst, as.data.table))
#   i index
#1: 3  6359
#2: 8  1609
#3: 8  2197
#4: 8  3045
#5: 9  1392
#6: 9  5831

data

lst <- list(NULL, NULL, structure(c(3, 6359), .Dim = 1:2, .Dimnames = list(
NULL, c("i", "index"))), NULL, structure(c(8, 8, 8, 1609, 
2197, 3045), .Dim = c(3L, 2L), .Dimnames = list(NULL, c("i", 
"index"))), structure(c(9, 9, 1392, 5831), .Dim = c(2L, 2L), .Dimnames = list(
NULL, c("i", "index"))), NULL)

Upvotes: 2

joel.wilson
joel.wilson

Reputation: 8413

since your code is throwing errors, i have created a sample list:

l = list(a = matrix(c(a = 1, b = "a"), ncol = 2), 
         b = matrix(c(a = c(2,3), b=c("a","b")), ncol = 2), 
         c = NULL)
#l
#$a
#     [,1] [,2]
#[1,] "1"  "a" 
#
#$b
#     [,1] [,2]
#[1,] "2"  "a" 
#[2,] "3"  "b" 
# 
#$c
#NULL

l <- lapply(l,  as.data.frame) # converting each `matrix` to `data.frame` since bind_rows works on this only
#l
#$a
#  V1 V2
#1  1  a
# 
#$b
#  V1 V2
#1  2  a
#2  3  b
# 
#$c
#data frame with 0 columns and 0 rows

library(dplyr)
bind_rows(l1)
#  V1 V2
#1  1  a
#2  2  a
#3  3  b

Upvotes: 1

Related Questions