The Pebble Game

The Pebble Game (alternative link) is a shiny application that simulates the pebble game. This is a simple game that has been developed by BIDD at the University of Bristol, to help a general audience understand the role of vaccination in preventing the onward transmission of infectious disease. It involves repeatedly drawing pebbles from a bag, which contains two distinct pebble types (to represent vaccinated and unvaccinated individuals). The number of pebbles that are drawn each round is dependent on the number of infect-able (i.e unvaccinated) cases drawn in the previous round, and the infectiousness of the simulated disease. For a more detailed explanation of the mechanics of the game, examples of using the app, suggested questions, and instructions for local installation continue reading. Otherwise enjoy exploring a simple system with complex dynamics!

Using the app

Whilst the Pebble Game has been designed to be user friendly, I've written a blog post that takes you through using the app in more detail. If in using the app you discover something that you think is worth sharing then please contact me either via twitter or email.

Some suggested questions

• Look up some real world disease reproduction numbers (the number that each diseased pebble infects). What effect does varying this have?
• For a given reproduction number what effect does varying the proportion of vaccinated pebbles have?
• What happens if you repeat the game using the same parameters multiple times? Can you explain this?
• How does population size effect the spread of the disease?

Playing the game for yourself

Whilst the web app fully captures the dynamics of the pebble game it may be useful to physically play the game for yourself. To do that follow the instructions below:

What you will need

• A bag or box (it is important that the pebbles cannot be seen).
• A set of pebbles/counters etc. of 2 different colours (these represent those who are vaccinated versus unvaccinated).
• Some paper to note down your results.

Set up

To play the game you must pick some basic parameters that define your pebble population and the disease. These are:

• The total number of pebbles (for best results it is suggested to use at least 50). The pebble population should be made up of;
• A number of vaccinated pebbles (choose a colour to represent this)
• A number of unvaccinated pebbles (using your other colour)
• The number of pebbles in the first generation of the disease (for the simplest game pick 1)
• The number of pebbles that each diseased pebble subsequently infects (in epidemiology this is known as the basic reproduction number).

Playing the game

1. Pick pebbles from the bag equal to the number in the first generation times the number that each diseased pebble infects.
2. Count the number of pebbles that are unvaccinated that you have picked, these are the next generation of infected pebbles (note this number down).
3. For the new generation multiply the number in the new generation against the number that each diseased pebble infects and pick this many pebbles from the bag.
4. Repeat steps 2. and 3. until you pick no unvaccinated pebbles or until the bag is empty.

Installing the shiny app locally

To install and run the shiny app locally on your own computer you will need to first install R, it is also suggested that you install Rstudio. After downloading the source code from this repository click on the thepebblegame.Rprof file, this will open an Rstudio window. Type the following code into the command line;

install.packages("shiny")
install.packages("shinydashboard")
install.packages("shinyBS")
install.packages("tidyverse")
install.packages("rmarkdown")


To run the app open the ui.R file and press run, depending on your computer this may take some time. Enjoy playing the pebble game!

Simulation Functions

### Pebble game outline
library(tidyverse)

### Input
## Number of simulations - slider
## R0 - slider
## Proportion Vaccinated - slider
## Population - slider

### Output
## Graph of Simulation Trends over time
## Summary stats of Trends over time

## Function to estimate the number of cases in a generation
no_in_gen <- function(df, vac_status = 'no') {
df %>%
filter(generation == max(generation, na.rm = TRUE),
vaccinated %in% vac_status) %>%
nrow
}

## Function to run a pebble game simulation
gen_pebble_game <- function(df, generation_no, r0, no_in_first_gen) {
##define sampled population
df_sampled <- filter(df, !is.na(generation))

## Calculated generation number
if (generation_no > 1) {
no_in_generation <- no_in_gen(df_sampled)
} else {
no_in_generation <- no_in_first_gen
}

## Restrict to unsampled pebbles
df_unsampled <- filter(df, is.na(generation))

## Sample pebbles
no_sample <- no_in_generation * r0

if (no_sample < length(df_unsampled$id)) { pebble_sample <- sample(df_unsampled$id, no_sample, replace = FALSE)
}else {
pebble_sample <- df_unsampled$id } df_unsampled <- mutate(df_unsampled, generation = replace(generation, id %in% pebble_sample, generation_no) ) ##Combine held back population with sampled population df <- bind_rows(df_sampled, df_unsampled) return(df) } ##Function to run a single simulation of the pebble game pebble_game <- function(r0, no_in_first_gen, prop_vac, population, verbose) { ## Check parameters population <- population %>% as.numeric ## number vaccinated no_vac <- round(prop_vac * population, digits = 0) ## create population in a data frame pebbles <- data_frame(id = seq(1, population, 1), vaccinated = c(rep("yes", no_vac), rep("no", population - no_vac)), generation = NA ) ## Define first generation generation_no <- 1 no_left_to_infect <- population - no_vac no_in_generation <- 1 ## Repeatedly sample pebbles while (no_left_to_infect > 0 & no_in_generation > 0) { ## Update pebbles pebbles <- gen_pebble_game(pebbles, generation_no = generation_no, r0 = r0, no_in_first_gen = no_in_first_gen) ## Check if there are any unvaccinated pebbles left no_left_to_infect <- filter(pebbles, is.na(generation), vaccinated %in% "no") %>% nrow ## Check if there are any unvaccinated pebbles ## in the current generation no_in_generation <- no_in_gen(pebbles) ## Advance generation number generation_no <- generation_no + 1 if (verbose) { message("The generation number is:", generation_no) } } return(pebbles) } ## Function to run multiple simulations of the pebble game multi_sim_pebble_game <- function(r0, no_in_first_gen, prop_vac, population, simulations, verbose = FALSE) { df <- map_df(1:simulations, function(sim) { if (verbose) { message("Starting simulation number:", sim) } df <- pebble_game(r0, no_in_first_gen, prop_vac, population, verbose) %>% mutate(simulation = sim) return(df) } ) ## clean up table df <- df %>% mutate(generation = as.integer(generation)) return(df) } ## generate summaries by generation for data - count summarise_pebble_game_sim <- function(df, simulations, population, prop_vac) { ## Parameter check population <- population %>% as.numeric ##Calc number unvaccinated no_unvac <- round((1 - prop_vac) * population, digits = 0) df_count <- df %>% filter(vaccinated %in% "no", !is.na(generation)) %>% group_by(simulation, generation) %>% count ## Detect simmulations that have no intial cases ## Add these to the data frame with a generation number of 1, and n = 0 df_count <- df_count %>% bind_rows(data_frame(simulation = 1:simulations, generation = 1, n = 0) %>% mutate(simulation = simulation %>% replace(simulation %in% unique(df_count$simulation), NA)
) %>%
na.omit
)

## Added in generations for which no pebbles were infected
zero_generations <- df_count %>%
group_by(simulation) %>%
filter(generation == max(generation)) %>%
do(data_frame(simulation = .$simulation, generation = seq(.$generation + 1, max(df_count$generation) + 1, 1), n = 0 ) ) ## Calculate cumulative sum and percentage of unvaccinated infected df_cum <- df_count %>% bind_rows(zero_generations) %>% group_by(simulation) %>% mutate(cumsum = cumsum(n)) %>% mutate(perinfect = round(cumsum / no_unvac * 100, digits = 0)) %>% rename(Generation = generation, Simulation = simulation, No. of pebbles = n, Cumulative no. of pebbles = cumsum, Percentage (%) of unvaccinated infected = perinfect) return(df_cum) } ##Add mean and ci to df df_mean_ci <- function(df, y, group_by) { ## Estimate mean and ci's df_trans <- df %>% group_by_(.dots = group_by) %>% mutate_(mean = paste0("mean(", y, ")")) %>% mutate_(sd = paste0("sd(", y, ")")) %>% mutate_(sqrt_sample = paste0("sqrt(length(", y, "))")) %>% ungroup %>% mutate(se = sd / sqrt_sample, lci = mean - 1.96 * se, uci = mean + 1.96 * se) return(df_trans) } ## Make ggplot for playing the game plot_pebbles <- function(df, y, colour = "dodgerblue2") { df <- df %>% df_mean_ci(y = y, group_by = c("Generation")) df %>% ggplot(aes_string(x = "Generation", y = y)) + geom_point(alpha = 0.2, colour = colour, aes(group = Simulation)) + geom_line(alpha = 0.2, colour = colour, aes(group = Simulation)) + geom_line(aes(x = Generation, y = mean), colour = colour, alpha = 1, size = 1.5) + geom_ribbon(aes(x = Generation, ymin = lci, ymax = uci), fill = "grey", alpha = 0.4) + theme_minimal() -> plot return(plot) } ## Make a ggplot for comparing diseases plot_pebbles_compare <- function(df, y) { df <- df %>% df_mean_ci(y = y, group_by = c("Disease", "Generation")) df %>% ggplot(aes_string(x = "Generation", y = y, colour = "Disease", group = "interaction(Disease, Simulation)")) + geom_point(alpha = 0.2) + geom_line(alpha = 0.2) + geom_line(aes(x = Generation, y = mean), alpha = 1, size = 1.5) + scale_colour_manual(values=c("dodgerblue2", "firebrick2")) + geom_ribbon(aes(x = Generation, ymin = lci, ymax = uci, group = Disease), fill = "grey", alpha = 0.4) + theme_minimal() + theme(legend.position = "bottom") -> plot return(plot) } ## Add a summary statistic add_sum_stat <- function(df, stat_vect, sum_measure) { df <- df %>% add_row(Summary Measure = sum_measure, Mean = stat_vect %>% mean, Median = stat_vect %>% median, 25% Quantile = stat_vect %>% quantile(probs = 0.25), 75% Quantile = stat_vect %>% quantile(probs = 0.75)) return(df) } ## Make table of summary data ## mean, medium, CI of generations reached ## summary_table <- function(df, population, prop_vac) { ## Check parameters population <- population %>% as.numeric ## Set up dataframe sum_tab <- data_frame(Summary Measure = NA, Mean = NA, Median = NA, 25% Quantile = NA, 75% Quantile = NA) ## No. in a generation sum_tab <- sum_tab %>% add_sum_stat(stat_vect = df$No. of pebbles,
sum_measure = "No. in a generation")

## no. of generations
no_of_generations <- df %>%
group_by(Simulation) %>%
filter(No. of pebbles > 0) %>%
summarise(no_of_gen = max(Generation))

sum_tab <- sum_tab %>%
add_sum_stat(stat_vect = no_of_generations$no_of_gen, sum_measure = "No. of generations") ## Totol no. of infected pebbles total_no_infected_pebbles <- df %>% group_by(Simulation) %>% summarise(total_infect = max(Cumulative no. of pebbles)) sum_tab <- sum_tab %>% add_sum_stat(stat_vect = total_no_infected_pebbles$total_infect,
sum_measure = "Total no. of infected")

## Number unvaccinated
no_unvac <- round((1 - prop_vac) * population, digits = 0)

## Calculate percentage of susceptible pop that are infected
## Tidy results
sum_tab <- sum_tab %>%
mutate_at(vars(Mean, Median, 25% Quantile, 75% Quantile), funs(as.character(as.integer(round(., digits = 0))))) %>%
bind_rows(sum_tab %>%
filter(Summary Measure %in% "Total no. of infected") %>%
mutate_at(vars(Mean, Median, 25% Quantile, 75% Quantile), funs(paste0(round(. / no_unvac * 100, digits = 0), "%"))) %>%
mutate(Summary Measure = "Percentage of unvaccinated infected")
)

## Clear first row
sum_tab <- sum_tab %>% na.omit

return(sum_tab)
}
## Wrap everything into a wrapper function for portability
sim_then_plot_pebble_game <- function(r0 = 3,
no_in_first_gen = 1,
prop_vac = 0.6,
population = 1000,
simulations = 100,
verbose = FALSE,
y = "No. of pebbles") {
plot <- multi_sim_pebble_game(r0 = r0,
no_in_first_gen = no_in_first_gen,
prop_vac = prop_vac,
population = population,
simulations = simulations,
verbose = verbose) %>%
summarise_pebble_game_sim %>%
plot_pebbles(y = y)
return(plot)
}

## Summary of functions
## df <- multi_sim_pebble_game(r0 = 3, no_in_first_gen = 1,prop_vac = 0.6, population = 1000, simulations = 100, verbose = FALSE)
## df_count <- df %>% summarise_pebble_game_sim(simulations = 100, population = 1000, prop_vac = 0.6)
## plot_pebbles(df_count, y = "No. of pebbles") %>% ggplotly
## plot_pebbles(df_count, y = "Cumulative no. of pebbles") %>% ggplotly

UI

## Load packages
library(shiny)
library(shinydashboard)
library(shinyBS)
library(tidyverse)
library(rmarkdown)

sidebar <- dashboardSidebar(
hr(),
menuItem("Play the game", tabName="pebble_game", icon=icon("line-chart"), selected=TRUE),
menuItem("Compare diseases", tabName = "disease_com", icon = icon("random")),
menuSubItem("Github", href = "https://github.com/seabbs/thepebblegame", icon = icon("github")),
menuSubItem("pebble_game.R", tabName = "pebble_game_code", icon = icon("angle-right")),
menuSubItem("ui.R", tabName = "ui", icon = icon("angle-right")),
menuSubItem("server.R", tabName = "server", icon = icon("angle-right"))
)
),
hr(),
helpText("Developed by ", a("Sam Abbott, ", href="http://samabbott.co.uk"),
a("Bristol Infectious Disease Dynamics, ", href="http://www.bristol.ac.uk/social-community-medicine/research/groups/bidd/"), "University of Bristol", style="padding-left:1em; padding-right:1em;position:absolute; bottom:1em; ")
)

body <- dashboardBody(
tabItems(
withMathJax(),
),
tabItem(tabName = "pebble_game",
fluidRow(
tags$head(includeScript("google-analytics.js")), column(width = 4, box( width = NULL, tipify(sliderInput("r0", "Reproduction no.:", min = 1, max = 50, value = 3), title = "The basic reproduction rate (R0) is used to measure the transmission potential of a disease. It is thought of as the number of secondary infections produced by a typical case of an infection in a population that is totally susceptible." ), tipify(sliderInput("no_in_first_gen", "No. in first generation:", min = 1, max = 50, value = 1), title = "The number of infected pebbles introduced into the population. Does altering this have any effect on the epidemic dynamics?"), tipify(sliderInput("prop_vac", "Proportion vaccinated:", min = 0, max = 1, value = 0.6), title = "The proportion of the population that have been vaccinated, the number that are vaccinated can be calulated by multiplying the proportion vaccinated by the population. Try to find the vaccination thresold at which an epidemic cannot occur."), tipify(radioButtons("population", label = "No. of pebbles:", choices = c(50, 100, 250, 500, 1000), selected = 100, inline = TRUE), title = "How many pebbles do you want to simulate? Does this alter the trend, or does it just alter the epidemic size? Note: A high population will take longer to compute." ), tipify(radioButtons("simulations", label = "No. of simulations:", choices = c(1, 10, 50, 100, 500, 1000), selected = 10, inline = TRUE), title = "How many times to repeat the game. What is the effect of increasing this? Note: A high number of simulations will take longer to compute" ), tipify(selectInput("sumstat", "Summary statistic to plot:", list(Cumulative no. of pebbles = "Cumulative no. of pebbles", No. of pebbles = "No. of pebbles", Percentage (%) of unvaccinated infected = "Percentage (%) of unvaccinated infected") ), title = "The cumulative number of pebbles (i.e. the rolling total) gives the clearest picture of the final epidemic size. The number of pebbles (in each generation) shows how the epidemic evolves over time. The percentage of unvaccinated infected allows diseases to be compared more easily." ), tipify(actionButton("play_button", "Simulate", style="color: #fff; background-color: #337ab7; border-color: #2e6da4"), title = "What effect does repeating the game with the same parameters have?" ), title = 'Game Parameters', status = "primary", solidHeader = FALSE, collapsible = TRUE, collapsed = TRUE )), column(width = 8, box(width = NULL, tipify(plotOutput("pebble_plot"), title = "Plot of the simulations of the game, overlayed with the mean and 95% confidence intervals. What effect does varying the parameters have?"), collapsible = TRUE, title = "Plot", status = "primary", solidHeader = FALSE ), tabBox( width = NULL, title = "Tables", side = "right", tabPanel(title = "Summary Statistics", id = "tabletab1", tipify(tableOutput("pebble_table"), title = "Summary statistics for the pebble game. How does varying the parameters effect these? Do these summary measures match what you see on the plot above?", placement = "top" ) ), tabPanel(title = "Simulation Data", id = "tabletab2", tipify(dataTableOutput("results_table"), title = "Simulation results from playing the pebble game, with your specified parameters. Download this with the button below and see what patterns you can find.", placement = "top" ), downloadButton('downloadDatatable', 'Download') ) ) ) ) ), tabItem(tabName = "disease_com", fluidRow( column(width = 4, box( width = NULL, tipify(sliderInput("r0_prim", "Primary disease R0:", min = 1, max = 50, value = 3), title = "The basic reproduction rate (R0) is used to measure the transmission potential of a disease. It is thought of as the number of secondary infections produced by a typical case of an infection in a population that is totally susceptible." ), tipify(sliderInput("r0_sec", "Secondary disease R0:", min = 1, max = 50, value = 12), title = "The basic reproduction rate (R0) is used to measure the transmission potential of a disease. It is thought of as the number of secondary infections produced by a typical case of an infection in a population that is totally susceptible." ), tipify(sliderInput("no_in_first_gen_com", "No. in first generation:", min = 1, max = 50, value = 1), title = "The number of infected pebbles introduced into the population. Does altering this have any effect on the epidemic dynamics?"), tipify(sliderInput("prop_vac_com", "Proportion vaccinated:", min = 0, max = 1, value = 0.6), title = "The proportion of the population that have been vaccinated, the number that are vaccinated can be calulated by multiplying the proportion vaccinated by the population. Try to find the vaccination thresold at which an epidemic cannot occur."), tipify(radioButtons("population_com", label = "No. of pebbles:", choices = c(50, 100, 250, 500, 1000), selected = 100, inline = TRUE), title = "How many pebbles do you want to simulate? Does this alter the trend, or does it just alter the epidemic size? Note: A high population will take longer to compute." ), tipify(radioButtons("simulations_com", label = "No. of simulations:", choices = c(1, 10, 50, 100, 500, 1000), selected = 10, inline = TRUE), title = "How many times to repeat the game. What is the effect of increasing this? Note: A high number of simulations will take longer to compute" ), tipify(selectInput("sumstat_com", "Summary statistic to plot:", list(Cumulative no. of pebbles = "Cumulative no. of pebbles", No. of pebbles = "No. of pebbles", Percentage (%) of unvaccinated infected = "Percentage (%) of unvaccinated infected") ), title = "The cumulative number of pebbles (i.e. the rolling total) gives the clearest picture of the final epidemic size. The number of pebbles (in each generation) shows how the epidemic evolves over time. The percentage of unvaccinated infected allows diseases to be compared more easily." ), tipify(actionButton("compare_button", "Simulate", style="color: #fff; background-color: #337ab7; border-color: #2e6da4"), title = "What effect does repeating the game with the same parameters have?" ), title = "Disease Parameters", status = "primary", solidHeader = FALSE, collapsible = TRUE, collapsed = TRUE )), column(width = 8, tabBox(width = NULL, title = "Plots", side = "right", tabPanel( title = "Comparision", id = "tabletab1", tipify(plotOutput("com_plot"), title = "Comparision plot of simulations of the game for both diseases, overlayed with the mean and 95% confidence intervals. Compare the difference between the trend line gradients, what does this mean?") ), tabPanel( title = "Primary Disease", id = "tabletab2", tipify(plotOutput("prim_plot"), title = "Plot of the simulations of the game for the primary disease, overlayed with the mean and 95% confidence intervals. What effect does varying the other parameters have?") ), tabPanel( title = "Secondary Disease", id = "tabletab3", tipify(plotOutput("sec_plot"), title = "Plot of the simulations of the game for the primary disease, overlayed with the mean and 95% confidence intervals. What effect does varying the other parameters have?") ) ), tabBox( width = NULL, title = "Primary Disease", side = "right", tabPanel(title = "Summary Table", tipify(tableOutput("prim_sum_tab"), title = "Summary statistics for the pebble game, played with the primary disease. How does varying the parameters effect these? Do these summary measures match what you see on the plot above and how do they correspond with those from the secondary disease?", placement = "top" ), id = "tabletab1" ), tabPanel(title = "Simulation Table", id = "tabletab2", tipify(dataTableOutput("prim_results_table"), title = "Simulation results from playing the pebble game with the primary disease, and your specified parameters. Download this with the button below and see what patterns you can find.", placement = "top" ), downloadButton("downloadPrimDatatable", "Download")) ), tabBox( width = NULL, title = "Secondary Disease", side = "right", tabPanel(title = "Summary Table", tipify(tableOutput("sec_sum_tab"), title = "Summary statistics for the pebble game, played with the secondary disease. How does varying the parameters effect these? Do these summary measures match what you see on the plot above and how do they correspond with those from the primary disease?", placement = "top" ), id = "tabletab1" ), tabPanel(title = "Simulation Table", id = "tabletab2", tipify(dataTableOutput("sec_results_table"), title = "Simulation results from playing the pebble game with the secondary disease, and your specified parameters. Download this with the button below and see what patterns you can find.", placement = "top" ), downloadButton("downloadSecDatatable", "Download") ) ) ) ) ), tabItem(tabName = "pebble_game_code", box( width = NULL, status = "primary", solidHeader = TRUE, title="Simulation Functions", downloadButton('downloadData1', 'Download'), br(),br(), pre(includeText("pebble_game.R")) ) ), tabItem(tabName = "ui", box( width = NULL, status = "primary", solidHeader = TRUE, title="UI", downloadButton('downloadData2', 'Download'), br(),br(), pre(includeText("ui.R")) ) ), tabItem(tabName = "server", box( width = NULL, status = "primary", solidHeader = TRUE, title="Server", downloadButton('downloadData3', 'Download'), br(),br(), pre(includeText("server.R")) ) ) ) ) dashboardPage( dashboardHeader(title = "The Pebble Game"), sidebar, body ) Server #Load packages library(shiny) library(shinydashboard) library(shinyBS) library(tidyverse) ## Source functions source("pebble_game.R") ## Stop spurious warnings options(warn = - 1) shinyServer(function(input, output) { ## Simulation the game ## Play the game simulation sim_sum <- reactive({ ## Depend on play button input$play_button

## Sim
sim <- multi_sim_pebble_game(r0 = input$r0, no_in_first_gen = input$no_in_first_gen,
prop_vac = input$prop_vac, population = input$population,
simulations = input$simulations) %>% summarise_pebble_game_sim(simulations = input$simulations,
population = input$population, prop_vac = input$prop_vac)

return(sim)
})

## Primary disease simulation
prim_sim <- reactive({
## depends on comparision button press
input$compare_button prim_sim <- multi_sim_pebble_game(r0 = input$r0_prim,
no_in_first_gen = input$no_in_first_gen_com, prop_vac = input$prop_vac_com,
population = input$population_com, simulations = input$simulations_com) %>%
summarise_pebble_game_sim(simulations = input$simulations_com, population = input$population_com,
prop_vac = input$prop_vac_com) return(prim_sim) }) ## Secondary disease simulation sec_sim <- reactive({ ## depends on comparision button press input$compare_button

sec_sim <- multi_sim_pebble_game(r0 = input$r0_sec, no_in_first_gen = input$no_in_first_gen_com,
prop_vac = input$prop_vac_com, population = input$population_com,
simulations = input$simulations_com) %>% summarise_pebble_game_sim(simulations = input$simulations_com,
population = input$population_com, prop_vac = input$prop_vac_com)

return(sec_sim)
})

## serve results table
## Play the game simulation
output$results_table <- renderDataTable({ sim_sum() }, options = list( pageLength = 10) ) ##Primary output$prim_results_table <- renderDataTable({
prim_sim()
},
options = list(
pageLength = 10)
)

##Secondary
output$sec_results_table <- renderDataTable({ sec_sim() }, options = list( pageLength = 10) ) ## Serve results plot - playing the game output$pebble_plot <- renderPlot({
## Run simulations, summarise and plot see pebble_game.R
plot <- sim_sum() %>%
plot_pebbles(y = input$sumstat) plot }) ## Serve primary disease plot output$prim_plot <- renderPlot({
## Run simulations, summarise and plot see pebble_game.R
plot <- prim_sim() %>%
plot_pebbles(y = input$sumstat_com) plot }) ## Serve secondary disease plot output$sec_plot <- renderPlot({
## Run simulations, summarise and plot see pebble_game.R
plot <- sec_sim() %>%
plot_pebbles(y = input$sumstat_com, colour = "firebrick2") plot }) ## Serve results plot for comparing disease output$com_plot <- renderPlot({
## Bind data
com_sim <- prim_sim() %>%
mutate(Disease = "Primary") %>%
bind_rows(sec_sim() %>%
mutate(Disease = "Secondary"))
## Run simulations, summarise and plot see pebble_game.R
plot <- com_sim %>%
plot_pebbles_compare(y = input$sumstat_com) plot }) ## Summary data tables ## Play the game output$pebble_table <- renderTable({
## generate summary df
sim_sum() %>% summary_table(population = input$population, prop_vac = input$prop_vac
)
})

## Primary disease
output$prim_sum_tab <- renderTable({ ## generate summary df prim_sim() %>% summary_table(population = input$population_com,
prop_vac = input$prop_vac_com ) }) ## Secondary disease output$sec_sum_tab <- renderTable({
## generate summary df
sec_sim() %>% summary_table(population = input$population_com, prop_vac = input$prop_vac_com
)
})

## Play the game
output$downloadDatatable <- downloadHandler(filename = "pebble_game_sim_results.csv", content = function(file) { write.csv(sim_sum(), file) } ) ## Primary disease output$downloadPrimDatatable <- downloadHandler(filename = "pebble_game_prim_disease_sim_results.csv",
content = function(file) {
write.csv(prim_sim(), file)
}
)

## Secondary disease
output$downloadSecDatatable <- downloadHandler(filename = "pebble_game_sec_disease_sim_results.csv", content = function(file) { write.csv(sec_sim(), file) } ) ## Set up downloadable scripts output$downloadData1 <- downloadHandler(filename = "pebble_game.R",
content = function(file) {
file.copy("pebble_game.R", file, overwrite = TRUE)
}
)
output$downloadData2 <- downloadHandler(filename = "ui.R", content = function(file) { file.copy("ui.R", file, overwrite = TRUE) } ) output$downloadData3 <- downloadHandler(filename = "server.R",
content = function(file) {
file.copy("server.R", file, overwrite = TRUE)
}
)

})