Wang
Wang

Reputation: 1460

Shiny: delete columns from a reactive variable

I would like to use shiny to read a CSV file, and then allow the user to be able to delete selected columns.

Below is my example. But I kept getting no applicable method for 'select' applied to an object of class "c('reactiveExpr', 'reactive', 'function')" error.

The delete function is already within a reactive environment, I don't know how to solve the problem.

Thanks a lot for your help.

library(shiny)

ui = fluidPage(
  fileInput(inputId = "rawFile", label="File"), 
  uiOutput("selectColumn"),
  actionButton(inputId = "Remove", label = "Remove"),
  tableOutput("DFTable")
)

server = function(input, output, session){
  # initiate a reactive value
  df <- reactiveValues(data = NULL)
  removecolumn <- function(df, nameofthecolumn){dplyr::select(df, -nameofthecolumn)}
  
  inputData <- reactive({
    inFile <- input$rawFile
    if (is.null(inFile)){return(NULL)}
    read.csv(inFile$datapath, header = T)
  })
  
  # update column names
  output$selectColumn <- renderUI({
    shiny::req(inputData())
    selectInput(inputId = "selectColumn",
                label = "Remove selected sample(s)",
                multiple = TRUE,
                choices = names(inputData())
                )
  })
  
  df$data <- reactive({inputData()})
  
  # delete column
  observeEvent(input$Remove, {
    df$data <- removecolumn(df$data, input$selectColumn)
  })
  
  # show result
  output$DFTable <- renderTable(df$data())
  
}

shinyApp(ui, server)

Upvotes: 0

Views: 259

Answers (1)

langtang
langtang

Reputation: 24722

Instead of assigning to df$data (i.e df$data<-reactive(inputData())), you can assign within the reactive for reading the raw data, like this:

  inputData <- reactive({
    inFile <- input$rawFile
    if (is.null(inFile)){return(NULL)}
    data = read.csv(inFile$datapath, header = T)
    df$data = data
    return(data)
  })

Then, we observe the input$Remove, and update df$data like this:

  observeEvent(input$Remove, {
      df$data <- removecolumn(df$data, input$selectColumn)
  })

Full Code:

library(shiny)

ui = fluidPage(
  fileInput(inputId = "rawFile", label="File"), 
  uiOutput("selectColumn"),
  actionButton(inputId = "Remove", label = "Remove"),
  tableOutput("DFTable")
)

server = function(input, output, session){
  # initiate a reactive value
  df <- reactiveValues(data = NULL)
  removecolumn <- function(df, nameofthecolumn){dplyr::select(df, -(all_of(nameofthecolumn)))}
  
  inputData <- reactive({
    inFile <- input$rawFile
    if (is.null(inFile)){return(NULL)}
    data = read.csv(inFile$datapath, header = T)
    df$data = data
    return(data)
  })
  
  # update column names
  output$selectColumn <- renderUI({
    shiny::req(inputData())
    selectInput(inputId = "selectColumn",
                label = "Remove selected sample(s)",
                multiple = TRUE,
                choices = names(inputData())
    )
  })
  
  ##df$data = reactive(inputData())
  
  observeEvent(input$Remove, {
      df$data <- removecolumn(df$data, input$selectColumn)
  })
  
  # show result
  output$DFTable <- renderTable({
    df$data
  })
  
}

shinyApp(ui, server)

Upvotes: 1

Related Questions