Search code examples
rshinyreactable

Converting Dataframe to Named List Programmatically


I am trying to use the formatting options in the Reactable library in R. I would like to create the formatting programmatically from a mapping dataframe.

Reactable Expects Format Declarion as

reactable(iris[1:5, ], columns = list(
  Sepal.Length = colDef(name = "Sepal Length"),
  Sepal.Width = colDef(name = "Sepal Width"),
  Species = colDef(align = "center")
))

But I already have a dataframe which maps Actual Columns to Display columns.

Is there a way to convert the mapping dataframe column to a named list. The mapping dataframe will have 2 columns, original-column and display-column

I would like to further expand this to, adding more addtributes. As further column formating looks like,

percent = colDef(format = colFormat(percent = TRUE, digits = 1)). 

I could simply add more columns to my dataframe.

I tried converting to this format using string concatenations, but that didnt work.

A sample code with iris data i have is,

df <- iris
colnames(df) <- c('sep_l', 'sep_w','pet_l','pet_w','spec')
df$per <- df$sep_w/df$sep_l

col2 <- c('sep-l', 'sep-w', 'pet-l','pet-w', 'species', 'pct')

df_mapping <- cbind(colnames(df) , col2) %>% as.data.frame()
colnames(df_mapping) <- c('og','new')

df_mapping %<>%
 mutate(
  fmt = paste0(og, ' = colDef(format = colFormat(percent = TRUE, digits = 1))')
 )

reactable(df, columns = list(df_mapping$fmt))

Solution

  • Here a solution using eval and parse, since it looks like you would like to run an expression using text chunks

    library(reactable)
    library(dplyr)
    library(magrittr)
    
    #get sample df
    df <- iris
    colnames(df) <- c('sep_l', 'sep_w','pet_l','pet_w','spec')
    df$per <- df$sep_w/df$sep_l
    
    col2 <- c('sep-l', 'sep-w', 'pet-l','pet-w', 'species', 'pct')
    
    df_mapping <- cbind(colnames(df) , col2) %>% as.data.frame()
    colnames(df_mapping) <- c('og','new')
    
    
    # add character strings that will be used for the list command below (you forgot name== in your example)
    df_mapping %<>%
      mutate(
        fmt = paste0(og,"= colDef(name='",paste(og),"'",",format = colFormat(percent = TRUE, digits = 1))"))
    
    
    
    # paste the code together
    text=paste0("list(",paste(df_mapping$fmt,collapse=","),")")
    
    # use parse (returns the parsed, but unevaluated expression) and eval (will evaluate the parsed expression)
    reactable(df, columns = eval(parse(text=text)))