Home > OS >  Convert named list of lists to dataframe using tidy approach
Convert named list of lists to dataframe using tidy approach

Time:02-23

I am trying to convert a named list of lists to a dataframe using tidy functions, such as those available in purrr. I tried solutions from here and here, but neither of them work for me (e.g., rows are not single observations). Also, neither option provided a solution on how to keep the object(?) names (e.g., e1m1_fit and e2m2a_fit) associated with the new rows in the dataframe.

library("tidyverse")

# The named list I am trying to convert to a dataframe/tibble:
df <-
  list(e1m1_fit = structure(list(term = c("(Intercept)", "log10(q)"), 
                                 estimate = c(2.7, -0.1), std.error = c(0.03, 0.01), 
                                 statistic = c(88.04, -15.55), 
                                 p.value = c(0.01, 0.01)), 
                            class = c("tbl_df", "tbl", "data.frame"), 
                            row.names = c(NA, -2L)), 
       e2m2a_fit = structure(list(term = c("(Intercept)", "log10(q)"), 
                                  estimate = c(2.7, -0.1), 
                                  std.error = c(0.03, 0.01), 
                                  statistic = c(79.78, -15.48), 
                                  p.value = c(0.01, 0.01)), 
                             class = c("tbl_df", "tbl", "data.frame"), 
                             row.names = c(NA, -2L)))

# I tried a solution like this, but a) it's not generalized/it's very specific to this example. 
# And I cannot figure out how to associate the correct parameter/coefficient estimate with the correct value (they all end up in the same row). 
# Also, it does not pass along the object name (e.g., e1m1_fit) to the new dataframe/tibble.

# A solution I tried that doesn't accomplish what I want:
df2 <- 
  df %>% 
  tibble(term = map(., "term"),
         estimate = map(., "estimate"),
         std_error = map(., "std.error"),
         statistic = map(., "statistic"),
         p_val = map(., "p.value")
         ) %>% 
  mutate(term1 = map_chr(term, 1),
         term2 = map_chr(term, 2),
         estimate1 = map_dbl(estimate, 1),
         estimate2 = map_dbl(estimate, 2))

Any help is greatly appreciated!

CodePudding user response:

We may use bind_rows which have the .id that creates a new column from the names of the list

library(dplyr)
 bind_rows(df, .id = "fitname")
# A tibble: 4 × 6
  fitname   term        estimate std.error statistic p.value
  <chr>     <chr>          <dbl>     <dbl>     <dbl>   <dbl>
1 e1m1_fit  (Intercept)      2.7      0.03      88.0    0.01
2 e1m1_fit  log10(q)        -0.1      0.01     -15.6    0.01
3 e2m2a_fit (Intercept)      2.7      0.03      79.8    0.01
4 e2m2a_fit log10(q)        -0.1      0.01     -15.5    0.01

In addition, if the df list was created by looping with map, the _dfr can return a single tibble/data.frame with the .id specified as the name of the list

library(purrr)
map_dfr(yourlist, ~ yourfun(.x), .id = "fitname")
  • Related