Elk
Elk

Reputation: 532

Dataframe into list with a specific format

I've been trying to get a dataframe into a list with specific formatting to work with downstream functionality, and I'm failing. It has to work regardless of the dataframe size.

Specifically, what I need is to turn these dataframes:

mycolours <- data.frame(Group=c("Group1","Group2"),
                       Colour=c("#F8766D","#7CAE00"))

mycolours2 <- data.frame(Group=c("Group1","Group2","Group3","Group4"),
                       Colour=c("#F8766D","#7CAE00","#00BFC4","#C77CFF"))

Into these lists:

mycolours <- list(Group = c(Group1 = "#F8766D", Group2 = "#7CAE00"))
mycolours2 <- list(Group = c(Group1 = "#F8766D", Group2 = "#7CAE00", Group3 = "#00BFC4", Group4 = "#C77CFF"))

I have already tried some solutions, which do work to an extent, but they aren't specific enough with the formatting to work downstream. Among other solutions I've already tried mycolours <- split(mycolours, seq(nrow(mycolours))) and mycolours <- purrr::transpose(mycolours) (these are wrong format) and mycolours <- lapply(as.list(1:dim(mycolours)[1]), function(x)df[x[1],]) (returns an error: object of type 'closure' is not subsettable).

Thanks!

Upvotes: 1

Views: 31

Answers (1)

user63230
user63230

Reputation: 4636

A horrible looking solution but it gets you there:

library(tidyverse)
list(mycolours %>%
       group_split(row_number(), .keep = FALSE) %>% 
       map(., ~ .x$Colour) %>% 
       unlist %>% 
       set_names(., mycolours$Group)) %>% 
  set_names(select(mycolours, matches("Group")) %>% names())
# $Group
#    Group1    Group2 
# "#F8766D" "#7CAE00" 

We can turn it into a function to make it more presentable:

df_to_list_function <- function(df, colour_variable, grouping_variable) {
  grouping_name <- select(df, matches(grouping_variable)) %>% names()
  list(df %>%
         group_split(row_number(), .keep = FALSE) %>%
         map(., ~ .[[colour_variable]]) %>%
         unlist %>%
         set_names(., df[[grouping_variable]])) %>%
    set_names(grouping_name)
}

Then calling it:

df_to_list_function(mycolours, "Colour", "Group")
# $Group
#    Group1    Group2 
# "#F8766D" "#7CAE00" 

df_to_list_function(mycolours2, "Colour", "Group")
# $Group
#    Group1    Group2    Group3    Group4 
# "#F8766D" "#7CAE00" "#00BFC4" "#C77CFF" 

Upvotes: 1

Related Questions