1

I have a list with 10000 nested lists containg two components ("x" and "y"). e.g.

iter1 <- list(x = c(8500, 8510, 8520, 8530), y = c(1.2, 1.3, 1.4, 1.5))
iter2 <- list(x = c(8490, 8500, 8510, 8520, 8530), y = c(1.2, 1.2, 1.3, 1.4, 1.5))
iter3 <- list(x = c(8510, 8520, 8530, 8540, 8550, 8560), y = c(1.2, 1.2, 1.3, 1.4, 1.5, 1.6))
All <- list(iter1 = iter1, iter2 = iter2, iter3 = iter3)

I'd like to create a dataframe and transfrom the y componenent from each and turn them into a column that corresponds to the matching x values to give something like below.

    #      iter1 iter2 iter3
    # 8490    NA   1.2    NA
    # 8500   1.2   1.2    NA
    # 8510   1.3   1.3   1.2
    # 8520   1.4   1.4   1.2
    # 8530   1.5   1.5   1.3
    # 8540    NA    NA   1.4
    # 8550    NA    NA   1.5
    # 8560    NA    NA   1.6

I have tried many ways but have so far failed. Is there an effective way to do this?

Many thanks, Graham

Graham
  • 11
  • 1

1 Answers1

0

you can create a 2-column dataframe for each list in All and join them.

library(dplyr)
library(purrr)

map(All, bind_rows) %>% 
    reduce(full_join, by = 'x') %>% 
    arrange(x) %>%
    rename_with(~names(All), -1)

# A tibble: 8 x 4
#      x iter1 iter2 iter3
#  <dbl> <dbl> <dbl> <dbl>
#1  8490  NA     1.2  NA  
#2  8500   1.2   1.2  NA  
#3  8510   1.3   1.3   1.2
#4  8520   1.4   1.4   1.2
#5  8530   1.5   1.5   1.3
#6  8540  NA    NA     1.4
#7  8550  NA    NA     1.5
#8  8560  NA    NA     1.6

The same in base R can be done as :

Reduce(function(x, y) merge(x, y, all = TRUE, by = 'x'), 
       lapply(All, function(x) do.call(cbind.data.frame, x)))
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
  • Great thanks. My R doesn't seem to recognise the 'rename_with' function from dplyr but the second method works well. – Graham Sep 08 '20 at 14:51
  • `rename_with` is in the newer version of `dplyr` (`dplyr 1.0.0`) In older version you can use `rename_at(-1, ~names(All))`. – Ronak Shah Sep 08 '20 at 14:54