I'm trying to understand why a cycling use of shiny's reactivevalues
causes it to use more memory. The context is a user interface with the option to automate a given strategy. The example below is based on the St. Petersburg paradox. I appreciate that it may be better practice to place the entire automation process in a seperate function file but I would like to understand why the reactive object increases in size and if there is a more immediate work around.
The example below will print out the amount of memory values
is using on the disk. There is no increase in size to the list saved to it.
library(shiny)
library(pryr)
server=shinyServer(function(input, output) {
values=reactiveValues(win=0,
total=1000,
gamble=0,
stick=0,
outcome=0,
auto.counter=0
)
#############################################
# update action from buttons
observe({
if(!is.null(input$stick)){
isolate({
values$stick=values$stick+1
})
}
})
observe({
if(!is.null(input$gamble)){
isolate({
values$gamble=values$gamble+1
})
}
})
#############################################
## perform stick action
observe({
if(values$stick>0){
isolate({
values$total=values$total+2^values$win
values$auto.counter=max(values$auto.counter-1,0)
values$win=0
cat("\nStick:",2^values$win)
cat("\nReactive values size:",object_size(values))
})
}
})
# perform gamble action
observe({
if(values$gamble>0){
isolate({
values$outcome=sample(1:2,1)
if(values$win==0){
values$total=values$total-input$entry
}
if(values$outcome==1){
output$print=renderText("Win")
values$win=values$win+1
} else {
output$print=renderText("Lose")
values$win=0
}
cat("\nGamble:",2^values$win)
cat("\nReactive values size:",object_size(values))
values$auto.counter=max(values$auto.counter-1,0)
})
}
})
#############################################
# automation input
observe({
if(input$automate>0){
isolate({
values$auto.counter=input$rep
})
}
})
# if automation on run until auto.counter==0
observe({
if(!is.null(values$auto.counter)){
if(values$auto.counter>0){
isolate({
if(2^values$win>input$target){
values$stick=values$stick+1
} else {
values$gamble=values$gamble+1
}
})
}
}
})
#############################################
# render views
output$total=renderText({paste("Total winnings:",values$total)})
output$currentvalue=renderText({paste("Current jackpot:",2^values$win)})
})
ui=shinyUI(fluidPage(
br(),
fluidRow(
column(
4,
numericInput(inputId="entry",label="Entry Fee",value=10),
actionButton(inputId="gamble",label='Gamble'),
actionButton(inputId="stick",label='Stick'),
h4("Automate"),
numericInput(inputId="target",label="Target value",value=20),
numericInput(inputId="rep",label="Turns",value=10),
actionButton(inputId="automate",label='Automate')
),
column(
8,
textOutput("currentvalue"),
textOutput("total"),
textOutput("print")
)
)
))
runApp(list(ui=ui,server=server))