Delay Reaction in R shiny - r

library(shiny)
library(ggplot2)
ui <- shinyUI(fluidPage(
titlePanel("Central Limit Theorem Simulation"),
sidebarLayout(
sidebarPanel(
numericInput("sample_size", "Size of each random sample\n(max: 100)",
value = 30, min = 1, max = 100, step = 1),
sliderInput("simulation", "The number of simulation",
value = 100, min = 100, max = 1000, step = 1),
numericInput("bins", "Number of bins in the histogram\n(max: 50)",
value = 20, min = 1, max = 50, step = 1),
selectInput("sample_dist", "Population Distribution where each sample is from",
choices = c("Bernoulli","Poisson", "Normal", "Uniform") ),
conditionalPanel(condition = 'input.sample_dist == "Bernoulli"',
textInput("prob", "Parameter (p)") ),
conditionalPanel(condition = 'input.sample_dist == "Poisson"',
textInput("lambda", "Parameter (lambda)") ),
conditionalPanel(condition = 'input.sample_dist == "Normal"',
textInput("mu", "Parameter (mu)"),
textInput("sigma", "Parameter (sigma)") ),
conditionalPanel(condition = 'input.sample_dist == "Uniform"',
textInput("min_a", "Parameter (a)"),
textInput("max_b", "parameter (b)") ),
actionButton("update", "Update Simulation")
),
mainPanel(
tabsetPanel(type = "pills",
tabPanel("mean of random sample mean", br(),
textOutput(outputId = "output_mean")),
tabPanel("variance of random sample mean", br(),
textOutput(outputId = "output_var")),
tabPanel("summary table", br(),
tableOutput(outputId = "output_table")),
tabPanel("sample matrix", br(),
verbatimTextOutput(outputId = "output_sample")),
tabPanel("histogram of random normal sample", br(),
plotOutput(outputId = "output_hist"))
)
)
)
))
server <- shinyServer(function(input, output) {
# Return the random sample
rsample <- eventReactive(input$update, {
if (isolate(input$sample_dist == "Bernoulli") ) {
rsample <- isolate(rbinom(n = input$sample_size * input$simulation,
size = 1, as.numeric(input$prob) ) )
} else if (isolate(input$sample_dist == "Poisson") ) {
rsample <- isolate(rpois(n = input$sample_size * input$simulation,
as.numeric(input$lambda) ) )
} else if (isolate(input$sample_dist == "Normal") ) {
rsample <- isolate(rnorm(n = input$sample_size * input$simulation,
mean = as.numeric(input$mu), sd = as.numeric(input$sigma) ) )
} else {
rsample <- isolate(runif(n = input$sample_size * input$simulation,
min = as.numeric(input$min_a), max = as.numeric(input$max_b) ) )
}
rsample
})
# Return the random sample matrix
rsamplematrix <- reactive({
matrix(rsample(), nrow = isolate(input$simulation) )
})
# output mean of sample mean
output$output_mean <- renderText({
sample_mean <- rowMeans(rsamplematrix())
mean(sample_mean)
})
# output variance of sample mean
output$output_var <- renderText({
sample_mean <- rowMeans(rsamplematrix())
var(sample_mean)
})
# output summary table of sample mean
output$output_table <- renderTable({
sample_mean <- rowMeans(rsamplematrix())
data.frame(mean(sample_mean), var(sample_mean))
})
# output the first 5 rows and 5 columns of the sample matrix
output$output_sample <- renderPrint({
k = rsamplematrix()
k[1:5, 1:5]
})
# output histogram of sample mean
output$output_hist <- renderPlot({
sample_mean <- rowMeans(rsamplematrix())
ggplot(data.frame(sample_mean), aes(x = sample_mean, y = ..density..)) +
geom_histogram(bins = isolate(input$bins), fill = "steelblue", col = "white")
})
})
shinyApp(ui = ui, server = server)
The code runs well, but there is a little problem with respect to Delay Reaction.
Suppose I run the simulation of binomial distribution with parameter=0.5, then all output would be generated. Then I choose a different distribution (for instance, normal distribution), before I render values to the parameters and click action button, the histogram plot is becoming grey for around a second. t seems that the server function is running although there is no change at all after that second.
What I wish is that when the distribution choice is made, the reaction are supposed to be delayed. So the server function should not run unless the action Button is clicked.
How can I fix this?

Related

Shiny feedbackDanger doesnt work inside eventReactive where function is called

I am begginer in shiny an I am stucked adding feedback in my app.
I have tried a few things like write this code inside the eventReactive function like use the function feedBackDanger.
Below, there is a simplified full code with the ui, the idea is that i need the user get some Error (but not the console Error) if he set 'zero' in kind variable when mean is 3,6 or 9.
Also the actionButton 'simulate' should be disable when this condition is selected.
ui <- shinyUI(fluidPage(
titlePanel(h1("Simulation", align = 'center')),
sidebarLayout(
sidebarPanel(
numericInput(inputId = "n", label = "Size of Sample", min = 1,
step = 1, value = 1),
numericInput(inputId = "mean", label = "Mean of Sample", min = 1,
step = 1, value = 1),
numericInput(inputId = "var", label = "Variance", min = 1,
step = 0.25, value = 1),
radioButtons("kind", "Sample kind", choices = c("two", "zero")),
actionButton("simulate", "Simulate"),
width = 200
),
mainPanel(
plotOutput("distPlot", width = 500, height = 500)
)
)
))
# Define server logic required to draw a histogram
server <- shinyServer(function(input, output, session) {
s_fin <-function(n,
mean,
var,
kind){
a <- rnorm(n, mean, var)
if(kind == 'two'){
a <- a + 2
}
if(kind == 'zero'& mean %in% c(3,6,9)){
print('ERROR: function error')
stop(call. = T)}
return(a)
}
simulation <- eventReactive(input$simulate,{
s_fin(n = input$n,
mean = input$mean,
var = input$var,
kind = input$kind)
})
output$distPlot <- renderPlot({
hist(simulation())
})
})
shinyApp(ui, server)
The next code works to me (a just add useShinyFeedback() in ui.R, and put the error function instead of print):
library(shinyFeedback)
ui <- shinyUI(fluidPage(
useShinyFeedback(),
titlePanel(h1("Simulation", align = 'center')),
sidebarLayout(
sidebarPanel(
numericInput(inputId = "n", label = "Size of Sample", min = 1,
step = 1, value = 1),
numericInput(inputId = "mean", label = "Mean of Sample", min = 1,
step = 1, value = 1),
numericInput(inputId = "var", label = "Variance", min = 1,
step = 0.25, value = 1),
radioButtons("kind", "Sample kind", choices = c("two", "zero")),
actionButton("simulate", "Simulate"),
width = 200
),
mainPanel(
plotOutput("distPlot", width = 500, height = 500)
)
)
))
# Define server logic required to draw a histogram
server <- shinyServer(function(input, output, session) {
s_fin <-function(n,
mean,
var,
kind){
a <- rnorm(n, mean, var)
if(kind == 'two'){
a <- a + 2
}
if(kind == 'zero'& mean %in% c(3,6,9)){
showFeedbackDanger(
inputId = "mean",
text = "Not use mean 3, 6 or 9"
)
shinyjs::disable("simulate")
}else{
hideFeedback("mean")
shinyjs::enable("simulate")
}
return(a)
}
simulation <- eventReactive(input$simulate,{
s_fin(n = input$n,
mean = input$mean,
var = input$var,
kind = input$kind)
})
output$distPlot <- renderPlot({
hist(simulation())
})
})
shinyApp(ui, server)

Calculate in Shinyapps

I want to calculate some values and return the values to my shiny app:
ui <- fluidPage(
sidebarLayout(
sidebarPanel(numericInput(inputId = "ME",
label = "Maternal effect:",
min = -1,
max = 1,
value = 0.5),
numericInput(inputId = "CE",
label = "Child effect:",
min = -1,
max = 1,
value = 0.5)
),
mainPanel(h3(textOutput("Power"))
)
)
)
server <- function(input, output) {
bzc <- sqrt(abs(input$CE)) * sign(input$CE)
bzm <- sqrt(abs(input$ME)) * sign(input$ME)
results <- bzc * bzm
output$Power <- renderPrint({results
})
}
shinyApp(ui = ui, server = server)
This doesnt apprear to work. Any tips on how to calculate in the shiny app?
The error-messages arise, because you have input-objects outside of the render-functions. If you want to calculate something, which you want to reuse in multiple plots, then use a reactive or observe-function.
For all other cases it is enough add the code for bzc, bzm and result inside the render-functions:
ui <- fluidPage(
sidebarLayout(
sidebarPanel(numericInput(inputId = "ME",
label = "Maternal effect:",
min = -1,
max = 1,
value = 0.5),
numericInput(inputId = "CE",
label = "Child effect:",
min = -1,
max = 1,
value = 0.5)
),
mainPanel(h3(textOutput("Power"))
)
)
)
server <- function(input, output) {
output$Power <- renderPrint({
bzc <- sqrt(abs(input$CE)) * sign(input$CE)
bzm <- sqrt(abs(input$ME)) * sign(input$ME)
results <- bzc * bzm
results
})
}
shinyApp(ui = ui, server = server)

How to add interactive textinput panel in R shiny

library(shiny)
library(ggplot2)
ui <- shinyUI(fluidPage(
titlePanel("Central Limit Theorem Simulation"),
sidebarLayout(
sidebarPanel(
numericInput("sample_size", "Size of each random sample\n(max: 100)",
value = 30, min = 1, max = 100, step = 1),
sliderInput("simulation", "THe number of simulation",
value = 100, min = 100, max = 1000, step = 1),
selectInput("sample_dist", "Population Distribution where each sample is from",
choices = c("Binomial","Poisson", "Normal", "Uniform") ),
numericInput("bins", "Number of bins in the histogram\n(max: 50)",
value = 20, min = 1, max = 50, step = 1),
submitButton(text = "Submit")
),
mainPanel(
tabsetPanel(type = "pills",
tabPanel("mean of random sample mean", br(),
textOutput(outputId = "output_mean")),
tabPanel("variance of random sample mean", br(),
textOutput(outputId = "output_var")),
tabPanel("summary table", br(),
tableOutput(outputId = "output_table")),
tabPanel("sample matrix", br(),
verbatimTextOutput(outputId = "output_sample")),
tabPanel("histogram of random normal sample", br(),
plotOutput(outputId = "output_hist"))
)
)
)
))
server <- shinyServer(function(input, output) {
# Return the random sample
rsample <- reactive({
if (input$sample_dist == "Binomial") {
rsample <- rbinom(input$sample_size * input$simulation, 1, 0.5)
} else if (input$sample_dist == "Poisson") {
rsample <- rpois(input$sample_size * input$simulation, 1)
} else if (input$sample_dist == "Normal") {
rsample <- rnorm(input$sample_size * input$simulation)
} else {
rsample <- runif(input$sample_size * input$simulation)
}
rsample
})
# Return the random sample matrix
rsamplematrix <- reactive({
matrix(rsample(), nrow = input$simulation)
})
# output mean of sample mean
output$output_mean <- renderText({
sample_mean <- rowMeans(rsamplematrix())
mean(sample_mean)
})
# output variance of sample mean
output$output_var <- renderText({
sample_mean <- rowMeans(rsamplematrix())
var(sample_mean)
})
# output summary table of sample mean
output$output_table <- renderTable({
sample_mean <- rowMeans(rsamplematrix())
data.frame(mean(sample_mean), var(sample_mean))
})
# output the first 5 rows and 5 columns of the sample matrix
output$output_sample <- renderPrint({
k = rsamplematrix()
k[1:5, 1:5]
})
# output histogram of sample mean
output$output_hist <- renderPlot({
sample_mean <- rowMeans(rsamplematrix())
ggplot(data.frame(sample_mean), aes(x = sample_mean, y = ..density..)) +
geom_histogram(bins = input$bins, fill = "steelblue", col = "white")
})
})
shinyApp(ui = ui, server = server)
The above code runs well. Suppose right now I want to add textinput of distribution parameters for each distribution (for example, p is parameter for Binomial distribution, mu and sigma are parameters for normal distribution). These parameters input pop out when I made a selection for sample distribution.
What should I do? Which function should I use?
If you want to keep the parameter inputs hidden unless a distribution is selected then I think you want a conditionalPanel.
For example:
conditionalPanel("!(output.plot)", textInput("size", "Size"))
This size input panel would only show when output$plot is not yet rendered.
In your case I think you can use an input in the same way.
conditionalPanel('input.sample_dist) != "Poisson"', textInput("parameter2", "Parameter 2"))
This would show parameter 2 only if Poisson is not selected.
You'll need to remove your submitButton to ensure the parameter fields update when you select a new distribution. Replace it with a generic actionButton if you want to keep the same function.
I'd also suggest using numericInput fields and setting the appropriate label, min, max and step with updateNumericInput for each case in the server function when sample_dist updates.

Use R shiny to simulate CLT by using different distribution

library(shiny)
library(ggplot2)
ui <- shinyUI(fluidPage(
titlePanel("Central Limit Theorem Simulation"),
sidebarLayout(
sidebarPanel(
numericInput("sample.size", "Size of each random sample",
value = 30, min = 1, max = 100, step = 1),
sliderInput("simulation", "THe number of simulation",
value = 100, min = 100, max = 1000, step = 1),
selectInput("sample.dist", "Population Distribution where each sample is from",
choices = c("Binomial","Poisson", "Normal", "Uniform") ),
numericInput("bins", "Number of bins in the histogram",
value = 20, min = 1, max = 50, step = 1),
submitButton(text = "Submit")
),
mainPanel(
h3('Illustrating outputs'),
h4('mean of random sample mean'),
textOutput(outputId = "output_mean" ),
h4('variance of random sample mean'),
textOutput(outputId = "output_var"),
h4("Table"),
tableOutput(outputId = "output_table"),
h4('histogram of random normal sample'),
plotOutput(outputId = "output_hist")
)
)
))
server <- shinyServer(function(input, output) {
# Return the random sample
rsample <- ifelse(
input$sample.dist == "Binomial", rbinom(input$sample.size * input$simulation, 1, 0.5),
ifelse(input$sample.dist == "Poisson", rpois(input$sample.size * input$simulation, 1),
ifelse(input$sample.dist == "Normal", rnorm(input$sample.size * input$simulation),
runif(input$sample.size * input$simulation) ) ) )
# Return the random sample matrix
rsample.matrix <- matrix(rsample, nrow = input$simulation)
# output mean of sample mean
output$output_mean <- renderText({
sample.mean <- rowMeans(rsample.matrix)
mean(sample.mean)
})
# output variance of sample mean
output$output_var <- renderText({
sample.mean <- rowMeans(rsample.matrix)
var(sample.mean)
})
# output histogram of sample mean
output$output_hist <- renderPlot({
sample.mean <- rowMeans(rsample.matrix)
ggplot(data.frame(sample.mean), aes(x = sample.mean)) +
geom_histogram(bins = input$bins)
})
})
shinyApp(ui = ui, server = server)
(1) The above codes are to create a shiny application to simulate random sample and verify Central Limit Theorem. However, since I just learned shiny, I have no idea where it is wrong.
(2) Also, if I want to change the parameter of a specific distribution based on the distribution selected by the user, what should I do?
The error returned from Rstudio is as follows:
Warning: Error in .getReactiveEnvironment()$currentContext: Operation not allowed without an active reactive context. (You tried to do something that can only be done from inside a reactive expression or observer.)
Stack trace (innermost first):
49: .getReactiveEnvironment()$currentContext
48: .subset2(x, "impl")$get
47: $.reactivevalues
46: $ [#4]
45: server [#4]
4: <Anonymous>
3: do.call
2: print.shiny.appobj
1: <Promise>
Error in .getReactiveEnvironment()$currentContext() :
Operation not allowed without an active reactive context. (You tried to do something that can only be done from inside a reactive expression or observer.)
The error says that code should be within a reactive or an observe statement. Have a look how I wrapped and used the variables
library(shiny)
library(ggplot2)
ui <- shinyUI(fluidPage(
titlePanel("Central Limit Theorem Simulation"),
sidebarLayout(
sidebarPanel(
numericInput("sample.size", "Size of each random sample",
value = 30, min = 1, max = 100, step = 1),
sliderInput("simulation", "THe number of simulation",
value = 100, min = 100, max = 1000, step = 1),
selectInput("sample.dist", "Population Distribution where each sample is from",
choices = c("Binomial","Poisson", "Normal", "Uniform") ),
numericInput("bins", "Number of bins in the histogram",
value = 20, min = 1, max = 50, step = 1),
submitButton(text = "Submit")
),
mainPanel(
h3('Illustrating outputs'),
h4('mean of random sample mean'),
textOutput(outputId = "output_mean" ),
h4('variance of random sample mean'),
textOutput(outputId = "output_var"),
h4("Table"),
tableOutput(outputId = "output_table"),
h4('histogram of random normal sample'),
plotOutput(outputId = "output_hist")
)
)
))
server <- shinyServer(function(input, output) {
# Return the random sample
rsample <- reactive({
ifelse(
input$sample.dist == "Binomial", rbinom(input$sample.size * input$simulation, 1, 0.5),
ifelse(input$sample.dist == "Poisson", rpois(input$sample.size * input$simulation, 1),
ifelse(input$sample.dist == "Normal", rnorm(input$sample.size * input$simulation),
runif(input$sample.size * input$simulation) ) ) )
})
# Return the random sample matrix
rsamplematrix <- reactive({
matrix(rsample(), nrow = input$simulation)
})
# output mean of sample mean
output$output_mean <- renderText({
sample.mean <- rowMeans(rsamplematrix())
mean(sample.mean)
})
# output variance of sample mean
output$output_var <- renderText({
sample.mean <- rowMeans(rsamplematrix())
var(sample.mean)
})
# output histogram of sample mean
output$output_hist <- renderPlot({
sample.mean <- rowMeans(rsamplematrix())
ggplot(data.frame(sample.mean), aes(x = sample.mean)) +
geom_histogram(bins = input$bins)
})
})
shinyApp(ui = ui, server = server)

Table output of values Shiny

I am trying to generate a table/list in Shiny of the values sampled from a probability distribution ( a list of the sampled values in a table format). I'm new to coding so this is like a foreign language to me. There is probably a lot of errors in the code although I can get it to run just not show the table.
library(shiny)
ui <- fluidPage(
sidebarPanel(
selectInput("dis","Please Select Probability Distribution Type:",
choices = c("Normal")),
sliderInput("sampleSize","Please Select Sample Size:",
min = 0,max = 5000,value = 1000,step = 100),
sliderInput("bins","Please Select Number of Bins:",
min = 1,max = 50,value = 10),
numericInput("sampleMean","Please Enter Sample Mean:",
min = 0,max = 5000,value = 2500,step = 10),
numericInput("sampleSd","Please Enter Standard Deviation:",
min = 0,max = 5000,value = 2,step = 10)
),
fluidRow(
column(12,
dataTableOutput("table"))
),
mainPanel(
plotOutput("histogram")
)
)
server <- function(input, output){
output$histogram <- renderPlot({
distType <- input$dis
n <- input$sampleSize
bins <- seq(min(input$bins), max(input$bins), length.out = input$bins + 1)
if(distType=="Normal"){
randomVec <- rnorm(n,mean = as.numeric(input$sampleMean),sd=as.numeric(input$sampleSd))
}
hist(randomVec,breaks=input$bins,col="red")
})
output$table <- renderDataTable({
distType <- input$dis
n <- input$sampleSize
if(distType=="Normal"){
randomVec <- rnorm(n,mean = as.numeric(input$sampleMean),sd= as.numeric(input$sampleSd))
}
sample(randomVec,100,replace = TRUE)
})
}
shinyApp(ui = ui, server = server)
From ?renderDataTable :
Arguments
expr An expression that returns a data frame or a matrix.
So you can do this:
output$table <- renderDataTable({
distType <- input$dis
n <- input$sampleSize
if(distType=="Normal"){
randomVec <- rnorm(n,mean = as.numeric(input$sampleMean),sd= as.numeric(input$sampleSd))
}
data.frame(sample(randomVec,100,replace = TRUE))
})

Resources