Reputation: 1162
I need a data table to update each time a different date range, # of decimals to display, or a common vs all set of variables is chosen by the user. The code below works, but I don't think it's "correct". The three variables I need the code to respond to (input$descr_daterange, input$descr_radio, and input$descr_decimals) are located within the renderDataTable function. That doesn't seem like the right way to do this.
observeEvent(input$descr_daterange, {
descr_date_inds <- reactiveValues()
descr_date_inds$begin_ind <- min(which(substr(inputData$qcdata$LDT,1,10) == input$descr_daterange[1]))
descr_date_inds$end_ind <- max(which(substr(inputData$qcdata$LDT,1,10) == input$descr_daterange[2]))
output$data_descr <- renderDataTable({
description <- descr(inputData$qcdata[descr_date_inds$begin_ind:descr_date_inds$end_ind,],transpose = TRUE, stats = input$descr_radio)
description <- description[-which(row.names(description) == 'RecNum'),]
if ('N.Valid' %in% colnames(description) & 'Pct.Valid' %in% colnames(description)){
description <- description[,-which(colnames(description) == 'N.Valid' | colnames(description) == 'Pct.Valid')]}
description <- round2(description[,2:ncol(description)],input$descr_decimals)
return(description)
autoWidth = TRUE
options=list(pageLength = 50)
})
})
I've seen code examples that list the variables like this:
observeEvent(c(input$descr_daterange, input$descr_decimals, input$descr_radio),
{...})
However, I get warnings that only the first of the list is being used. How do I code this to get it to to work correctly?
Upvotes: 0
Views: 541
Reputation: 160407
You were close: put all reactive inputs to cause a trigger within braces.
Try this:
observeEvent({
input$descr_daterange
input$descr_decimals
input$descr_radio
}, {
descr_date_inds <- reactiveValues()
descr_date_inds$begin_ind <- min(which(substr(inputData$qcdata$LDT,1,10) == input$descr_daterange[1]))
descr_date_inds$end_ind <- max(which(substr(inputData$qcdata$LDT,1,10) == input$descr_daterange[2]))
output$data_descr <- renderDataTable({
description <- descr(inputData$qcdata[descr_date_inds$begin_ind:descr_date_inds$end_ind,],transpose = TRUE, stats = input$descr_radio)
description <- description[-which(row.names(description) == 'RecNum'),]
if ('N.Valid' %in% colnames(description) & 'Pct.Valid' %in% colnames(description)){
description <- description[,-which(colnames(description) == 'N.Valid' | colnames(description) == 'Pct.Valid')]}
description <- round2(description[,2:ncol(description)],input$descr_decimals)
return(description)
autoWidth = TRUE
options=list(pageLength = 50)
})
})
By-the-ways:
reactiveValues()
tend to belong outside of reactive blocks, and used/referenced within them. I don't know the rest of your app nor how you intend to use them, so it might be that you don't need it at all (and are just using its list/env functionality), in which case you are carrying unneeded overhead by doing it this way.
You should never use &
or |
within an if
conditional unless it is wrapped in any
or all
or some aggregating function. if
requires its conditional to be exactly length 1, whereas &
/|
are vectorized logical ands/ors, meaning they can be length 0 or more.
Even if both sides of the &
are length-1, there is still a reason: &&
short-circuits, &
does not.
### short-circuiting
TRUE || stop("hello")
# [1] TRUE
### not
TRUE | stop("hello")
# Error: hello
Lastly, it's a bit declarative, in that by forcing yourself to use &&
, you have to think about the length of the conditional. By using &
, you're implying (to whomever is reading/using your code) that you will accept a result of length other than 1 ... which doesn't always work cleanly for if
.
Upvotes: 3