1

I am creating a R shiny app that takes a CSV file as input and has three options:

  1. 'Browse' to load the CSV file

  2. 'SplitColumn' removes spaces from merged columns, my CSV may have merged columns at times.

  3. 'Replace' and 'By' are used to replace specific column values.

  4. 'Columns List' All three functions above use the column name from the column list to work.

Issue: The problem is that I keep getting the message "object of type 'closure' is not subsettable." How can I get rid of this error so that I can use all of the functions listed above?

Could someone help me on this?

Sample CSV

ID  Type  Category    Range
21  A1B1              100
22  C1D1              200
23  E1F1              300

Expected results after using the 'Split column' and 'Repalce' 'BY' buttons

ID  Type  Category    Range
21  A1     B1          5000
22  C1     D1          200
23  E1     F1          300

app.R

library(shiny)
library(reshape2)
library(DT)
library(tibble)
library(tidyverse)


###function for deleting the rows
splitColumn <- function(data, column_name) {
  newColNames <- c("Unmerged_type1", "Unmerged_type2")
  newCols <- colsplit(data[[column_name]], " ", newColNames)
  after_merge <- cbind(data, newCols)
  after_merge[[column_name]] <- NULL
  after_merge
}



ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      fileInput("file1", "Choose CSV File", accept = ".csv"),
      checkboxInput("header", "Header", TRUE),
      actionButton("Splitcolumn", "SplitColumn", class = "btn-warning" ),
      uiOutput("selectUI"),
      selectInput("col", "Columns List:", NULL),
      textInput("old", "Replace:"),
      textInput("new", "By:"),
      actionButton("replace", "Replace!"),
      
      
    ),
    mainPanel(
      DTOutput("table1")
    )
  )
)

server <- function(input, output, session) {
  rv <- reactiveVal(NULL)
  
  observeEvent(input$file1, {
    file <- input$file1
    ext <- tools::file_ext(file$datapath)
    req(file)
    validate(need(ext == "csv", "Please upload a csv file"))
    
    rv$orig <- read.csv(file$datapath, header = input$header)
    rv$data <- rv$orig
    updateSelectInput(session, "splitcolumn", choices = names(rv$data()))
  })
  
  observeEvent(input$replace, {
    req(input$splitcolumn)
    dat <- req(rv$data())
    traf <- if (is.numeric(dat[[input$Splitcolumn]])) as.numeric else identity
    rv$data(dat %>%
              mutate(!!rlang::sym(input$Splitcolumn) := 
                       replace(!!rlang::sym(input$Splitcolumn),
                               as.character(!!rlang::sym(input$Splitcolumn)) == input$old,
                               input$new) %>% 
                       traf()))
  })
  
  output$table1 <- renderDT(
    req(rv$data())
  )
  
  observeEvent(input$Splitcolumn, {
    rv$data <- splitColumn(rv$data, input$selectcolumn)
  })
}
shinyApp(ui, server)
Kevin Tracey
  • 154
  • 1
  • 16
  • 1
    Is that `rv$data()` valid? What is `data` supposed to be in that context? – dario Oct 11 '21 at 08:29
  • @dario, `rv$data`, is referencing the csv output – Kevin Tracey Oct 11 '21 at 08:31
  • 1
    But `rv$data` is totally not the same as `rv$data()`. The first references a element called "data" the second a function. Then at other places you try to use the `names` method on the function call - not sure what *that* is supposed to do – dario Oct 11 '21 at 08:32
  • 1
    @dario, since I am new to R shiny, could you assist me how I should get rid of this error? – Kevin Tracey Oct 11 '21 at 11:08
  • 1
    I won't be able to teach you shiny... I've already given some tips and asked questions, you could start by checking them. If you are new to R I'd highly suggest learning the basics first before trying to build a shiny app – dario Oct 11 '21 at 11:13

1 Answers1

1

reactiveVal only creates a (single) reactive value. I.e. it is not subsettable as you try it in cases like rv$orig. Use reactiveValues instead.

Taken from the manual:

# Create the object with no values
values <- reactiveValues()

# Assign values to 'a' and 'b'
values$a <- 3
values[['b']] <- 4

## Not run: 
# From within a reactive context, you can access values with:
values$a
values[['a']]

Jan
  • 4,974
  • 3
  • 26
  • 43