library(shiny)
library(ggplot2)
library(ProbBayes)
require(gridExtra)
require(dplyr)
# Define UI ----
ui <- fluidPage(
# titlePanel("Visualizing Posterior of Two Proportions"),
h2(id="big-heading", "Learning About Two Proportions Using a Discrete Prior"),
tags$style(HTML("#big-heading{color: red;}")),
fluidRow(
column(4, wellPanel(
h4(id="prior-heading", "Select Prior:"),
tags$style(HTML("#prior-heading{color: red;}")),
sliderInput("P",
"Choose Limits of Each P:",
min = 0,
max = 1,
value = c(0.05, 0.95)),
sliderInput("N", "# of Values:",
min = 5, max = 50,
value = 10,
step = 5),
radioButtons("type", "Prior Type:",
c("Uniform" = "unif",
"Testing" = "test")),
h4(id="data-heading", "Enter Data:"),
tags$style(HTML("#data-heading{color: red;}")),
h4(id="data-heading1", "Sample 1:"),
# tags$style(HTML("#data-heading1{color: red;}")),
fluidRow(
column(2, HTML('<h5><b>s1:</b></h5>')),
column(4, numericInput("s1", "", min = 0, max = 100, value = 0)),
column(2, HTML('<h5><b>f1:</b></h5>')),
column(4, numericInput("f1", "", min = 0, max = 100, value = 0))
),
h4(id="data-heading2", "Sample 2:"),
# tags$style(HTML("#data-heading2{color: red;}")),
fluidRow(
column(2, HTML('<h5><b>s2:</b></h5>')),
column(4, numericInput("s2", "", min = 0, max = 100, value = 0)),
column(2, HTML('<h5><b>f2:</b></h5>')),
column(4, numericInput("f2", "", min = 0, max = 100, value = 0))
)
)),
column(8,
tabsetPanel(type = "tabs",
tabPanel("Story",
br(),
img(src="model.png",
height = 424, width = 530)
),
tabPanel("Data",
tableOutput("stats")),
tabPanel("Prior",
plotOutput("prior1",
height = "500px")),
tabPanel("Post",
plotOutput("post1",
height = "500px")),
tabPanel("Prior/Post of Diff",
plotOutput("post2",
height = "500px")),
tabPanel("Post CDF of Diff",
plotOutput("post3",
height = "500px"))
)
)
)
)
# Define server logic ----
server <- function(input, output) {
data <- reactive({
bivariate_prob <- function(lo, hi, n_values,
pequal = 0.5,
uniform = FALSE,
s1f1 = c(0, 0),
s2f2 = c(0, 0)){
n_diagonal <- n_values
n_off_diag <- n_values ^ 2 - n_values
p1 <- seq(lo, hi, length = n_values)
p2 <- p1
grid <- expand.grid(p1, p2)
names(grid) <- c("p1", "p2")
grid$p1Mp2 <- round(grid$p1 - grid$p2, 3)
if(uniform == TRUE){
grid$prior <- 1 / (n_values ^ 2)
} else {
grid$prior <- (grid$p1 == grid$p2) *
pequal / n_values +
(grid$p1 != grid$p2) *
(1 - pequal) / n_off_diag
}
## update
grid$posterior <- log(grid$prior) +
dbinom(s1f1[1],
size = sum(s1f1),
prob = grid$p1,
log = TRUE) +
dbinom(s2f2[1],
size = sum(s2f2),
prob = grid$p2,
log = TRUE)
grid$posterior <- exp(grid$posterior -
max(grid$posterior))
grid$posterior <- grid$posterior /
sum(grid$posterior)
###########
grid %>%
group_by(p1Mp2) %>%
summarize(Prior = sum(prior),
Posterior = sum(posterior),
.groups = "drop") -> S
S$Prior <- round(S$Prior, 4)
S$Posterior <- round(S$Posterior, 4)
names(S)[1] <- "p1-p2"
list(grid = grid,
Summary = S)
}
flag <- ifelse(input$type == "unif", TRUE, FALSE)
out <- bivariate_prob(input$P[1], input$P[2],
input$N,
pequal = 0.5,
uniform = flag,
s1f1 = c(input$s1, input$f1),
s2f2 = c(input$s2, input$f2))
mdata <- matrix(c(input$s1, input$f1,
input$s2, input$f2),
2, 2, byrow = TRUE)
dimnames(mdata)[[2]] <- c("Successes", "Failures")
dimnames(mdata)[[1]] <- c("Sample 1", "Sample 2")
list(grid = out$grid,
S = out$Summary,
data = mdata)
})
output$prior1 <- renderPlot({
out <- data()
ggplot(out$grid,
aes(p1, p2, size = prior)) +
geom_point() +
increasefont() +
centertitle() +
ggtitle("Joint Prior Distribution of P1 and P2")
})
output$prior2 <- renderPlot({
S <- data()$S
names(S)[1] <- "p12"
prob_plot(select(S, p12, Prior)) +
increasefont() +
ggtitle("Prior of p1 MINUS p2") +
centertitle() +
xlab("p1 - p2") + ylab("Probability")
})
output$post1 <- renderPlot({
ggplot(data()$grid,
aes(p1, p2, size = posterior)) +
geom_point() +
increasefont() +
centertitle() +
ggtitle("Joint Posterior Distribution of P1 and P2")
})
output$post2 <- renderPlot({
S <- data()$S
names(S)[1] <- "p12"
M <- max(c(S$Prior, S$Posterior))
p1 <- prob_plot(select(S, p12, Prior)) +
increasefont() +
ggtitle("Prior of p1 MINUS p2") +
centertitle() +
ylim(0, M * 1.1) +
xlab("p1 - p2") + ylab("Probability")
p2 <- prob_plot(select(S, p12, Posterior)) +
increasefont() +
ggtitle("Posterior of p1 MINUS p2") +
centertitle() +
ylim(0, M * 1.1) +
xlab("p1 - p2") + ylab("Probability")
grid.arrange(p1, p2, ncol = 1)
})
output$post3 <- renderPlot({
S <- data()$S
names(S)[1] <- "p12"
S$cprob <- cumsum(S$Posterior)
ggplot(S, aes(p12, cprob)) +
geom_line(size = 1.5, color = "red") +
increasefont() +
ggtitle("CDF of P1 - P2") +
centertitle() +
xlab("p1 - p2") + ylab("Cumulative Probability")
})
output$mplot <- renderPlot({
out <- data()
p1 <- ggplot(out$sim_post, aes(x)) +
geom_density(size = 2, color = "red") +
xlab("theta1") +
ggtitle("Difference in Logits") +
increasefont() + centertitle()
p2 <- ggplot(out$sim_post, aes(y)) +
geom_density(size = 2, color = "red") +
xlab("theta2") +
ggtitle("Sum of Logits") +
increasefont() + centertitle()
grid.arrange(p1, p2, ncol = 1)
})
output$stats <- renderTable({
as.data.frame(data()$data) -> df
df$Sample <- c("Sample 1", "Sample 2")
df$'Sample Size' <- df[, 1] + df[, 2]
df[, c(3, 1, 2, 4)]
})
output$stats2 <- renderTable({
data()$S
})
}
# Run the app ----
shinyApp(ui = ui, server = server)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.