I am trying to combine caching of plots alongside debouncing the input data. I have an app that tests this, with the first graph being cached, and the second one not being cached. Unfortunately, when I've tried doing so, the following problem occurs:
If I change the first input "y range", the first graph does not update, while the second one does. If I change the second or third checkbox inputs, then both graphs update. It appears as if the first checkbox input is not being used as a cache key, despite being explicitly included in both the bindCache()
call and the shiny:::extractCacheHint()
call.
Am I going about this incorrectly, or is this a bug?
library(shiny)
library(tidyverse)
ui <- fluidPage(
titlePanel('Example Title'),
sidebarLayout(
sidebarPanel(
checkboxGroupInput(
'yFilterCheckbox',
label='Filter Checkbox',
choices = c('y<=-1','-1<y<1','y>=1'),
selected = c('y<=-1','-1<y<1','y>=1'),
),
checkboxGroupInput(
'cat1FilterCheckbox',
label='Category 1 Filter',
choices=LETTERS[1:4],
selected=LETTERS[1:4]
),
checkboxGroupInput(
'cat2FilterCheckbox',
label='Category 2 Filter',
choices=c('BIG','SMALL'),
selected = c('BIG','SMALL')
)
),
mainPanel(
plotOutput('myPlot1'),
plotOutput('myPlot2')
)
)
)
server <- function(input, output){
library(tidyverse)
set.seed(2021*12*21)
N=100000
mydata = data.frame(
x1 = rnorm(N),
x2 = rnorm(N),
x3 = rnorm(N),
c1 = sample(LETTERS[1:4], N, replace=T),
c2 = sample(c('BIG','SMALL'), N, replace=T)
) %>%
mutate(
y1 = x1 * (1 + (c1 == 'D')) +
x2 * (1 - (c1 == 'C')) +
(x3 - rnorm(N)) * (1 + 3 * (c2 == 'BIG')),
z1 = 1 * (y1 > 0)
)
# reactives
yFilterCheckbox_r <- reactive(
input$yFilterCheckbox
)
yFilterCheckbox_d = yFilterCheckbox_r %>%
debounce(1000)
cat1FilterCheckbox_r <- reactive(
input$cat1FilterCheckbox
)
cat1FilterCheckbox_d <- cat1FilterCheckbox_r %>%
debounce(1000)
cat2FilterCheckbox_r <- reactive(
input$cat2FilterCheckbox
)
cat2FilterCheckbox_d <- cat2FilterCheckbox_r %>%
debounce(1000)
filtered_data <- reactive({
print('filtering...')
mydata %>%
filter(
c1 %in% cat1FilterCheckbox_d() &
c2 %in% cat2FilterCheckbox_d() &
case_when(
y1 <= -1 ~ 'y<=-1' %in% yFilterCheckbox_d(),
y1 > -1 & y1 < 1 ~ '-1<y<1' %in% yFilterCheckbox_d(),
TRUE ~ 'y>=1' %in% yFilterCheckbox_d()
)
)
})
output_myPlot1 <- reactive({
print('plot 1')
ggplot(
filtered_data()
) +
geom_point(
aes(x=x1,y=y1, color=c1, shape=c2)
) + theme_bw()
}) %>%
bindCache(
input$yFilterCheckbox,
input$cat1FilterCheckbox,
input$cat2FilterCheckbox
)
output_myPlot2 <- reactive({
print('plot 2')
ggplot(
filtered_data()
) +
geom_point(
aes(x=x2,y=y1, color=c1, shape=c2)
) + theme_bw()
})
shiny:::extractCacheHint(output_myPlot1)
output$myPlot1 <- renderPlot({output_myPlot1()})
output$myPlot2 <- renderPlot({output_myPlot2()})
}
shinyApp(ui=ui, server=server)