Home > Software engineering >  Rewrite variable in reactive output
Rewrite variable in reactive output

Time:12-17

I have a problem with rewrite variable in reactive output. In my code df1() is uploaded main dataset. In modified_df1 i changed data type of variable based on user select. My problem is, in final dataset modified_df1 a I get only new column var (because I use cbind(df1(), var)). Is there some way, how I can rewrite previous column, no add new with cbind()? I pase server code here, thanks.

  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 = "") 
     
   })
   
   ## update when selection changes
   
   # storing the selected variable from the variables list table 
   table.sel <- reactive({
     df1()[,which(colnames(df1()) == col.name()[input$class_var,1])]
   })
   

   
  modified_df1 = eventReactive(input$chg_class,{
    if( input$choose_class == "Numeric"){
       var <- as.numeric(df1()[, input$class_var])
     } else if(input$choose_class == "Factor"){ message("get new vars");
       var <- as.factor(df1()[, input$class_var])
     } else if( input$choose_class == "Character"){
       var <- as.character(df1()[, input$class_var])
     } else if( input$choose_class == "Date"){
       var <- as.Date(df1()[, input$class_var])
     } 
    
    df2 = cbind(df1(), var)
    
   })

CodePudding user response:

Since we are selecting multiple columns, we can use dplyr::across to loop through them. For example if you want to change the columns selected to a character:

var <- df1() %>% mutate(across(all_of(input$class_var), ~as.character(.)))

I made an app to ilustrate better what's happening.

library(shiny)
library(tidyverse)

write_csv(iris, file = "iris.csv")

# ui ----------------------------------------------------------------------


ui <- fluidPage(
  fluidRow(
    column(
      width = 6,
      fileInput(
        "file1",
        "Upload File",
        multiple = FALSE,
        accept = NULL,
        width = NULL,
        buttonLabel = "Browse...",
        placeholder = "No file selected"
      ),
      checkboxGroupInput("class_var", "Select Columns", choices = "", selected = ""),
      radioButtons("choose_class", "Select Columns", choices = c("Numeric", "Factor", "Character", "Date")),
      actionButton("chg_class", "Change Class")
    ),
    column(
      width = 6,
      tableOutput("table_df")
    )
  )
)

# server ------------------------------------------------------------------


server <- function(input, output, session) {
  df1 <- reactive({
    req(input$file1)
    read.csv(input$file1$datapath)
  })



  colnames <- reactive({
    names(df1())
  })

  observeEvent(df1(), {
    updateCheckboxGroupInput(session,
      "class_var",
      label = "Select Columns",
      choices = colnames(),
      selected = ""
    )
  })


  ## update when selection changes

  # storing the selected variable from the variables list table
  table.sel <- reactive({
    df1()[, which(colnames(df1()) == col.name()[input$class_var, 1])]
  })



  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") {
      message("get new vars")
      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(.)))
    }

    var
  })



  output$table_df <- renderTable({
    modified_df1()
  })
}

shinyApp(ui, server)

Note that if you try to convert to Date a character vector an error will occur.

enter image description here

  • Related