1
votes

This question extends from another question that correctly explains how to use a button to subset a dataframe based on a slider.

I need a bit more specific help with my real problem.

I have a function "transition_matrix" in my server.R that takes 2 inputs: (a) a dataframe containing product information and (b) a date. I pre-load the dataframe as fixed but then allow the user to change the date. So, when the user changes the date, the function executes for the given dataframe and the selected date.

The code thus far:

server.R

shinyServer(function(input, output) {

  bigmatrix <- reactive({
    transition_matrix(capital_summary_cum, ceiling_date(as.Date(input$datebox),"month")-1)
  })

output$balance_matrix <- renderTable({
    balances_ <- bigmatrix()[1:(default_state +2),] %>%
      round(digits = 0) %>% 
      format(big.mark = ",") 

  transition_matrix <- function(df1, date1){
    date2 <- ceiling_date(as.Date(AddMonths(date1,1)),"month")-days(1)
    ...
    ...

What I want to do next is to allow the user to subset the dateframe as well. To do this I offer a group of checkboxes which represent products. So, in addition to the date, the user can also select a subset of products on which to perform the aforementioned function.

The problem is that the function takes approx 1.5 seconds to execute, so each time the user will check a box (of which there are approx 40) the function will be called creating an unwanted 1.5 sec delay.

I rather want to isolate (?) the checkboxes to allow the user to select the desired list of products until a button is clicked. Once the button is clicked I want to subset the dataframe based on the selected checkboxes, and only then feed this into the function. I really would like the date input to remain "fully reactive" so that i don't have to press the button each time the date is also changed.

How can I add a button that will subset my dataframe based on selected checkboxes and automatically call the function with the selected date?

1
What would happen if you use eventReactive instead of reactive for your bigmatrix function? Note that you need input$datebox as the first argument for eventReactive. If this does not give you the desired outcome, perhaps the checkboxes are inspected somewhere else in your code. - Kota Mori
Alternatively, you can use isolate for the checkboxes so that the shiny ignores the update in those. Shiny will ignore the isolated objects, so it does not refresh the page when they are updated. I don't see checkboxes in your code, but guess they are somewhere in transition_matrix function. - Kota Mori
At this stage I do not know how to add the checkboxes so that they are "isolated" but triggered with a button. Do I add it in the "bigmatrix" reactive function? If so, how do I "trigger" it with a button? Sorry I am really new with R.. - gmarais
No problem. The trick is you create an actionButton and refers to it within your bigmatrix function. The button does not affect the calculation outcome itself, but by doing so the function is triggered when the button is clicked. - Kota Mori
Thanks Kota, I am not sure but bigmatrix is supposed to return a dataset (which is calculated from transition_matrix function). I don't believe I can just randomly reference a button in bigmatrix because it is expecting a dataset and nothing more? If I am misunderstanding, then how and where exactly do I add a reference to the actionButton? - gmarais

1 Answers

1
votes

I think this is something similar to what you want to achieve. Note:

Use eventReactive to specify what your app to react to. In this case, the get_table function reacts to the update button and the checkbox for date, while the checkbox for variables does not trigger the function.

For your information, the actionButton has a integer value inside and the value increments by one when clicked. The app detects the changes in the value and trigger the function.

library(shiny)
ui <- list(checkboxGroupInput("varbox", "Variable", choices = c("x", "y")),
           br(), br(),
           checkboxGroupInput("datebox", "Date", choices = c("1", "2", "3")),
           br(), br(),
           actionButton("btn", "update"),
           tableOutput("tbl")) 

server <- function(input, output) {

  sub_fun <- function(dates, variables) {
    # sub function to create table
    # this does not have any reactive element inside
    tmp <- data.frame(day = rep(1:3, 4), x = 1:12, y = 13:24)
    tmp[tmp$day %in% dates, c("day", variables), drop = FALSE]
  }

  get_table <- eventReactive({input$btn; input$datebox}, {
    # reactive function to define the configulation
    sub_fun(as.character(input$datebox), input$varbox)
  })  

  output$tbl <- renderTable({
    get_table()
  })
}

runApp(list(ui = ui, server = server))