4
votes

So I have a list with me as below, what I want is to split them into three separate dataframes (with names as Banana/Strawberry & apple) as shown in expected output. I have already seen this (Splitting List into dataframe R) but its exact opposite of what I want. I dont want to combine then I want to split them into three dataframe with same name as list header.

list_a <- list(`Banana` = c(8.7), `Strawberry` = c(2.3), `Apple` = c(3.5))

DF1

Banana
8.7

DF2

Strawberry
2.3

DF3

Apple
3.5

Any Solution preferably in Tidyverse would be greatly appreciated. Actual problem has lot more columns in the list.

4

4 Answers

7
votes

First convert them all to a tibble:

list_a <- list(`Banana` = c(8.7), `Strawberry` = c(2.3), `Apple` = c(3.5))
list_a <- purrr::map(list_a, tibble::as_tibble)

Then send this to the global environment:

list2env(list_a, envir = .GlobalEnv)
4
votes

We can use imap to get the names and then use set_names

library(purrr)
library(dplyr)
library(stringr)
imap(list_a, ~ set_names(tibble(.x), .y)) %>%
        set_names(str_c("DF", 1:3)) %>% 
        list2env(.GlobalEnv)

DF1
# A tibble: 1 x 1
#  Banana
#   <dbl>
#1    8.7
DF2
# A tibble: 1 x 1
#  Strawberry
#       <dbl>
#1        2.3
DF3
# A tibble: 1 x 1
#  Apple
#  <dbl>
#1   3.5

If we need separate columns

library(tibble)
enframe(list_a) %>% 
     unnest(c(value)) %>% 
     group_split(rn = row_number(), keep = FALSE) %>%
     set_names(str_c("DF", 1:3)) %>% 
     list2env(.GlobalEnv)
DF1
# A tibble: 1 x 2
#  name   value
#  <chr>  <dbl>
#1 Banana   8.7
DF2
# A tibble: 1 x 2
#  name       value
#  <chr>      <dbl>
#1 Strawberry   2.3
DF3
# A tibble: 1 x 2
#  name  value
#  <chr> <dbl>
#1 Apple   3.5
3
votes

A tidyverse way would be

library(tidyverse)

new_list <- set_names(map2(list_a,names(list_a),  
                    ~tibble(!!.y := .x)), str_c("df", 1:3))

and it can be done in base R as well

new_list <- setNames(Map(function(x, y) setNames(data.frame(x), y), 
                    list_a,names(list_a)), paste0("df", 1:3))

Now we can write it into global environment.

list2env(new_list, .GlobalEnv)
2
votes

Less straightforward than previous answers but you can get it using a for loop:

for(i in 1:length(list_a))
{
  df <- data.frame(unlist(list_a[[i]]))
  colnames(df) <- names(list_a[i])
  assign(names(list_a[i]),df, .GlobalEnv)
}