1

I am trying to edit columns in a data frame yjay I uploadin using fileInput, however I keep getting the error "Operation not allowed without an active reactive context. (You tried to do something that can only be done from inside a reactive expression or observer.)". Does anybody know why I might be getting this error? Any help is greatly apprenticed!!

server = function(input, output) {

  a1 = reactive({
    if(is.null(input$myFile$datapath)) NULL
    else{
      read_excel(input$myFile$datapath)
    }
  })


  x <- as.POSIXct(a1()$Month)

  a1()$mo <- strftime(x, "%m")
  a1()$yr <- strftime(x, "%Y")
  a1()$qrt <- quarter(x, with_year = FALSE, fiscal_start = 01)

  #subsetting data to display sales reps that hold a quota 

  newdata <- a1()[grepl("Y", a1()$`Quota Held Flag`),]

  #fixing participation column into categorical for donut chart
  newdata$Participation[is.na(newdata$Participation)] <- 0
  newdata$Participation <- factor(newdata$Participation, labels = 
                                    c("0-99%","100%")) 

  #grouping data
  newdata2 <- newdata %>%
    group_by(yr, mo, qrt) 
}
shinyApp(ui = ui, server = server)
  • You need to call `a1()` from inside a reactive environment. When do you want all the code to set the `mo`, `yr` and `qrt` values to run? I assume that needs to happen any time `myFile` is updated. You can either move those transormations into the `a1` reactive value, or create a new reactive value, say `newdata` that depends on `a1`. If you are new to shiny, maybe check out [these videos](https://www.rstudio.com/resources/webinars/shiny-developer-conference/) to learn the basics of reactive programming. – MrFlick Dec 13 '18 at 19:57
  • Does this https://stackoverflow.com/q/20201070/2679518 help? – John Paul Dec 13 '18 at 20:05
  • thank you for helping @MrFlick! I am pretty new to shiny so i am having trouble understanding what you mean by calling a1() inside a reactive environment. Do you think you could show a short example? also, i appreciate the video links, definitely going to dive into those during Christmas break. –  Dec 13 '18 at 20:08
  • @JohnPaul are you saying to use a1 = reactiveDataInput instead of just reactive? –  Dec 13 '18 at 20:22
  • I guess what I am thinking is that once your read in a1, don't try to change it. Instead, make some new reactive data.frame that is based on the changes to a1 and mo, yr and qrt as columns. – John Paul Dec 13 '18 at 20:26

1 Answers1

3

The code in the server() function really should only set up reactive objects and respond to reactive events. You shouldn't have any data manipulation data in the body of the server() function itself because when that runs the data is not yet available. Something like this makes more sense

ui <- fluidPage(
  fluidPage(
    titlePanel("Uploading Files"),
    fileInput('myFile', 'Choose File'),
    tableOutput('contents')
  )
)
server <- function(input, output) {

  a1 <- reactive({
    req(input$myFile)
    read_excel(input$myFile$datapath)
  })

  newdata <- reactive({
    a1 <- a1()
    x <- as.POSIXct(a1$Month)

    a1$mo <- strftime(x, "%m")
    a1$yr <- strftime(x, "%Y")
    a1$qrt <- quarter(x, with_year = FALSE, fiscal_start = 01)

    newdata <- a1[grepl("Y", a1$`Quota Held Flag`),]

    #fixing participation column into categorical for donut chart
    newdata$Participation[is.na(newdata$Participation)] <- 0
    newdata$Participation <- factor(newdata$Participation, labels = c("0-99%","100%")) 

    #grouping data
    newdata %>%
      group_by(yr, mo, qrt)     
  })

  output$contents <- renderTable(        
    newdata()        
  )

}
shinyApp(ui = ui, server = server)

Notice how a1 reads the file that the user uploads. Then the newdata reactive object will update whenever a1 updates and will transform the data for you. Then we can hook up that to an output so it will actually be processed.

MrFlick
  • 195,160
  • 17
  • 277
  • 295
  • this helps paint the picture a lot better, thank you so much! So when calling for the data from the uploaded file I should call newdata(), not a1()? –  Dec 13 '18 at 20:49
  • Well, if you want the raw data, use `a1()`, that will be exactly what the user uploaded. But if you want all the changes and filters applied, use `newdata()`. They both will exist and work, they will just contain different things. It all depends on what you want to do with them in the end. – MrFlick Dec 13 '18 at 20:51
  • I got it all to work, I appreciate all of the new insights! –  Dec 13 '18 at 21:03