-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlongrun.R
100 lines (90 loc) · 3.4 KB
/
longrun.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# Probability Apps: Shiny apps for exploring probability and statistics
# longrun.R: Long-run Probability module
# Copyright 2016 Michael J. Culbertson <[email protected]>
#
# Probability Apps is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# Probability Apps is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
# for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with Probability Apps. If not, see <http://www.gnu.org/licenses/>.
library(dplyr)
library(shiny)
library(ggplot2)
longrun.UI <- function(id) {
ns <- NS(id)
tagList(
fluidRow(
column(4, wellPanel(
numericInput(ns('p'), 'Success Probability', 0.5, 0, 1, width='6em'),
numericInput(ns('N'), 'Number of Trials', 10, 0, width='6em'),
actionButton(ns('run'), 'Simulate'),
actionButton(ns('clear'), 'Reset'),
checkboxInput(ns('animate'), 'Animate', value=T)
)),
column(6, textOutput(ns('cum')), plotOutput(ns('plot'))),
column(2, uiOutput(ns('log')))
))
}
longrun <- function(input, output, session, colors) {
rv <- reactiveValues(
data=data.frame(x=logical(), cum=numeric(), i=integer(), cumProp=numeric())
)
# Clear the current data
observe({
input$clear ; input$p
rv$data <- slice(isolate(rv$data), 0)
rv$n <- 0
})
# Simulate
observeEvent(input$run, {
if (input$p > 0 && input$p < 1 && input$N > 0) {
lastCum <- last(rv$data$cum, default=0)
lastI <- last(rv$data$i, default=0)
rv$data <- bind_rows(rv$data,
data.frame(x=(runif(input$N) < input$p)) %>%
mutate(cum=cumsum(x)+lastCum,
i=row_number()+lastI,
cumProp=cum/i) )
if (!input$animate) rv$n <- nrow(rv$data)
}
})
# Animate
observe({
if (isolate(rv$n) < nrow(rv$data)) {
if (isolate(input$animate)) {
rv$n <- isolate(rv$n) + 1
invalidateLater(10)
} else rv$n <- nrow(rv$data)
}
})
# Plot data
output$cum <- renderText({
if (rv$n > 0)
sprintf('Cumulative proportion = %g/%g = %.3f',
rv$data$cum[rv$n], rv$n, rv$data$cumProp[rv$n])
else ''
})
output$plot <- renderPlot({
validate(need(input$p > 0 && input$p < 1,
"Success probability must be between 0 and 1"),
need(input$N > 0, "Number of trials must be greater than 0"))
ggplot(if (rv$n > 0) slice(rv$data, 1:rv$n) else rv$data, aes(i, cumProp)) +
geom_line() + ylim(0, 1) +
geom_hline(yintercept=isolate(input$p), color=colors$mean) +
labs(x='Trial Number', y='Cumulative Proportion') +
theme(panel.background=element_blank(), axis.line=element_line('black'),
title=element_text('Lato', size=16), axis.text=element_text('Lato', size=12) )
})
# Show outcomes list
output$log <- renderUI({
tags$textarea(paste(if (rv$n > 0) c('Failure', 'Success')[1+rv$data$x[1:rv$n]],
collapse='\n'), rows=20, cols=10, readonly=T)
})
}