Search code examples
rshinyshiny-servershiny-reactivity

Rewrite reactive dataset in R Shiny


I have problem with reactive dataset. I use eventReactive() to change column data type in reactive dataset df1. It works fine. New dataset with changed column data type is modified_df1. But now, when i want to change datatype in another column, previous change will be reset. It is because i still use df1 as main dataframe beafore change. Is there some way how to rewrite df1 beafore second datatype change?

 df1 <- reactive({
      req(input$file1)
      df <- read.csv(input$file1$datapath,
                     header = input$header,
                    sep = input$sep,
                    quote = input$quote)
     df
   })
   
   
   colnames <- reactive({ 
     names(df1()) })
   
   observeEvent(df1(), {
     updateCheckboxGroupInput(session, "class_var",
                              label = "Select Columns",
                              choices = colnames(),
                              selected = "") 
   })

 modified_df1 <- eventReactive(input$chg_class, {
     if (input$choose_class == "Numeric") {
       var <- df1() %>% mutate(across(all_of(input$class_var), ~ as.numeric(.)))
     } else if (input$choose_class == "Factor") {
       var <- df1() %>% mutate(across(all_of(input$class_var), ~ as.factor(.)))
     } else if (input$choose_class == "Character") {
       var <- df1() %>% mutate(across(all_of(input$class_var), ~ as.character(.)))
     } else if (input$choose_class == "Date") {
       var <- df1() %>% mutate(across(all_of(input$class_var), ~ as.Date(.)))
     }else if (input$choose_class == "Integer") {
       var <- df1() %>% mutate(across(all_of(input$class_var), ~ as.integer(.)))
     }
   })

Solution

  • Not sure my answer is appropriate because you don't provide a lot of information.

    I would use only one reactive dataframe df1, but not with a reactive conductor, with a reactive value instead:

    df1 <- reactiveVal(original_dataframe)
    

    And then I would modify it with an observer:

    observeEvent(input$chg_class, {
         if (input$choose_class == "Numeric") {
           df1(df1() %>% mutate(across(all_of(input$class_var), ~ as.numeric(.))))
         } else if (input$choose_class == "Factor") {
           df1(df1() %>% mutate(across(all_of(input$class_var), ~ as.factor(.))))
         } else if (input$choose_class == "Character") {
           df1(df1() %>% mutate(across(all_of(input$class_var), ~ as.character(.))))
         } else if (input$choose_class == "Date") {
           df1(df1() %>% mutate(across(all_of(input$class_var), ~ as.Date(.))))
         }else if (input$choose_class == "Integer") {
           df1(df1() %>% mutate(across(all_of(input$class_var), ~ as.integer(.))))
         }
       })
    

    EDIT

    df1 <- reactiveVal()
    
    observeEvent(input$file1, {
         df <- read.csv(input$file1$datapath,
                        header = input$header,
                        sep = input$sep,
                        quote = input$quote)
         df1(df)
    })
       
    observeEvent(df1(), {
         updateCheckboxGroupInput(session, "class_var",
                                  label = "Select Columns",
                                  choices = names(df1()),
                                  selected = "") 
    })
    
    observeEvent(input$chg_class, {
         if (input$choose_class == "Numeric") {
           df1(df1() %>% mutate(across(all_of(input$class_var), ~ as.numeric(.))))
         } else if (input$choose_class == "Factor") {
           df1(df1() %>% mutate(across(all_of(input$class_var), ~ as.factor(.))))
         } else if (input$choose_class == "Character") {
           df1(df1() %>% mutate(across(all_of(input$class_var), ~ as.character(.))))
         } else if (input$choose_class == "Date") {
           df1(df1() %>% mutate(across(all_of(input$class_var), ~ as.Date(.))))
         }else if (input$choose_class == "Integer") {
           df1(df1() %>% mutate(across(all_of(input$class_var), ~ as.integer(.))))
         }
    })