简体   繁体   中英

relevel a reactive variable in shiny

I would like to use shiny to read a CSV file, and then allow the user to be able to choose the reference level in a specific column of that file. Imagine a data like this:

mydata <- data.frame(letter = rep(letters[1:3], 3), num = 1:9)
write.csv(mydata, "mydata.csv", row.names = FALSE)

Here is my code:

library(shiny)
ui <- fluidPage(
  fileInput(
    "file",
    label = "File Input",
    accept = ".csv"
  ),
  selectInput(
    inputId = "ref",
    label = "Reference Outcome",
    choices = NULL
  ),
  actionButton( inputId = "action",
                label = "action"),
  textOutput("text")
)

server <- function(input, output, session) {
  observe({
    updateSelectInput(session,
                      "ref",
                      choices = unique(data()[,1]))
  })

  data <- reactive({
    inFile <- req(input$file)
    fileinput <- read.csv(inFile$datapath, header = TRUE, stringsAsFactors = FALSE)
    return(fileinput)
  })
  
  observeEvent(input$action,{
    data()$letter <- factor(data()$letter)
    data()$letter <- relevel(data()$letter, ref = input$ref)
    output$text <- renderText({
      paste("Your reference level is: ", levels(data()$letter)[1])
    }) 
  })  
}
shinyApp(ui, server)

I get this error :

Warning: Error in <-: invalid (NULL) left side of assignment
  [No stack trace available]

I know that you should not use a reactive variable on the left side of the assignment, but how do I relevel the data after it was imported as a reactive variable?

Try this

server <- function(input, output, session) {
  rv <- reactiveValues(df=NULL)
  observe({
    updateSelectInput(session,
                      "ref",
                      choices = unique(data()[,1]))
  })
  
  data <- reactive({
    inFile <- req(input$file)
    fileinput <- read.csv(inFile$datapath, header = TRUE, stringsAsFactors = FALSE)
    return(fileinput)
  })
  
  observeEvent(input$action,{
    rv$df <- data()
    rv$df$letter <- factor(rv$df$letter)
    rv$df$letter <- relevel(rv$df$letter, ref = input$ref)
    output$text <- renderText({
      paste("Your reference level is: ", levels(rv$df$letter)[1])
    }) 
  })  
}

Here is pretty much the same answer, except that the dataframe value is not updated every time you click on the action button. It's only updated when the file is uploaded.

library(shiny)

mydata <- data.frame(letter = rep(letters[1:3], 3), num = 1:9)
write.csv(mydata, "mydata.csv", row.names = FALSE)
  
  
ui <- fluidPage(
  fileInput(
    "file",
    label = "File Input",
    accept = ".csv"
  ),
  selectInput(
    inputId = "ref",
    label = "Reference Outcome",
    choices = NULL
  ),
  actionButton( inputId = "action",
                label = "action"),
  textOutput("text")
)

server <- function(input, output, session) {
  observe({
    updateSelectInput(session,
                      "ref",
                      choices = unique(data()[,1]))
  })
  
  data <- reactive({
    inFile <- req(input$file)
    fileinput <- read.csv(inFile$datapath, header = TRUE, stringsAsFactors = FALSE)
    r$df <- fileinput
  })
  
  r <- reactiveValues(
    df = NULL
  )

  observeEvent(input$action,{
    r$df$letter <- factor(r$df$letter)
    r$df$letter <- relevel(r$df$letter, ref = input$ref)
    output$text <- renderText({
      paste("Your reference level is: ", levels(r$df$letter)[1])
    }) 
  })  
}
shinyApp(ui, server)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM