Table output of values Shiny - r

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))
})

Related

Extract a value from reactive data frame in shiny

I am not sure how I extract a value from a reactive data frame and use it for calculation. The reactive output did not show up so I could not calculate what I want it the end. When I run the script below, I got an error as "$ operator is invalid for atomic vector"
Exercise<-c(A,B,C)
Var1<-c(60,90,50)
Var2<-c(0.5,0.7,0.3)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(numericInput(inputId = "Time1",
label = "Duration:",
min = 0,
max = 120,
value = 1),
selectInput(
inputId = "Drill1",
label = "Drill1",
choices = Exercise,
selected = "1")
),
mainPanel(h3(textOutput("Power"))
)
)
)
server <- function(input, output) {
d<- reactive({
res<-T1 %>%
filter(Exercise == input$Drill1)
res
})
output$Power <- renderPrint({
dataset <-d()
Int<-dataset$Var1[dataset$Exercise == input$Drill1]
results<-Time1*Int
results
})
}
I really appreciate your help in advance.
I tidied up your code a little bit and ran it in a new R session. Unfortunately, I couldn't reproduce this issue. The app below runs fine on my machine.
library(shiny)
library(dplyr)
T1 <- data.frame(
Exercise = c("A", "B", "C"),
Var1 = c(60, 90, 50),
Var2 = c(0.5, 0.7, 0.3)
)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
numericInput(
inputId = "Time1",
label = "Duration:",
min = 0,
max = 120,
value = 1
),
selectInput(
inputId = "Drill1",
label = "Drill1",
choices = T1$Exercise
)
),
mainPanel(h3(textOutput("Power")))
)
)
server <- function(input, output) {
d <- reactive({
filter(T1, Exercise == input$Drill1)
})
output$Power <- renderPrint({
dataset <- d()
Int <- dataset$Var1[dataset$Exercise == input$Drill1]
input$Time1*Int
})
}
shinyApp(ui, server)

edit a reactive database

Trying to edit a reactive database so that updates to the database are reflected in the output.
Have tried numerous variants, but none are working, general idea is shown - where I would like to have the figure update with changes to the database.
library(tidyverse)
library(shiny)
library(DT)
# Define UI for application that draws a histogram
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput("ages", "Max age:", 10, 100, 15),
sliderInput("nsamp",
"Sample size:",
min = 10,
max = 1000,
value = 100)),
mainPanel(dt_output('Sample sizes and weighting', 'x1'),
plotOutput("fig"))
)
)
server <- function(input, output) {
x = reactive({
df = data.frame(age = 1:input$ages,
samples = input$nsamp,
weighting = 1)
})
output$x1 = renderDT(x(),
selection = 'none',
editable = TRUE,
server = TRUE,
rownames = FALSE)
output$fig = renderPlot({
ggplot(x(), aes(age, samples)) +
geom_line() +
geom_point()
})
}
shinyApp(ui = ui, server = server)
We can use input$x1_cell_edit and reactiveValues to modify the data that is passed to the plot.
Note the use of isolate inside renderDT, that is to prevent the table from re-rendering when db$database is modified.
library(tidyverse)
library(shiny)
library(DT)
# Define UI for application that draws a histogram
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput("ages", "Max age:", 10, 100, 15),
sliderInput("nsamp",
"Sample size:",
min = 10,
max = 1000,
value = 100
)
),
mainPanel(
dataTableOutput("x1"),
plotOutput("fig")
)
)
)
server <- function(input, output) {
# all the data will be stored in this two objects
db <- reactiveValues(database = NULL)
# to store the modified values
edited_vals <- reactiveVal(tibble(row = numeric(), col = numeric(), value = numeric()))
# create a new table each time the sliders are changed
observeEvent(c(input$ages, input$nsamp), {
df <- data.frame(
age = 1:input$ages,
samples = input$nsamp,
weighting = 1
)
db$database <- df
})
observeEvent(input$x1_cell_edit, {
db$database[as.numeric(input$x1_cell_edit$row), as.numeric(input$x1_cell_edit$col + 1)] <- as.numeric(input$x1_cell_edit$value)
})
output$x1 <- renderDT(
{
input$ages
input$nsamp
datatable(
isolate(db$database),
selection = "none",
editable = TRUE,
rownames = FALSE,
options = list(stateSave = TRUE)
)
},
server = TRUE
)
output$fig <- renderPlot({
ggplot(db$database, aes(as.numeric(age), as.numeric(samples))) +
geom_point() +
geom_line()
})
}
shinyApp(ui = ui, server = server)

Initial scaling in shiny

I've got a problem using the shiny package in R. I'm trying to insert income. debt and bonus entered in the slider that I've built into the original data set so the algorithm can scale i.e. normalise the data to make the calculation. Right now I can only make the calculation as-is i.e. when you enter the data it calculates it however, as I indicated, I want the data entered to go back into the original data set so I can scale it before making the calculation. I have the below code for the shiny package.
library(shiny)
shinyUI(fluidPage(
headerPanel("Calculating fwbs"),
sidebarPanel(
sliderInput("Income", "Please Select Income: ", min=0, max=5000,
value=2500, step=100),
sliderInput("Debt", "Please Select Debt: ", min = 0, max=2500,
value=1250, step = 100),
sliderInput("Bonus", "Have you received any bonus: ", min=0, max= 1000,
value=500, step =100)
),
mainPanel(
textOutput("fwbi")
)
))
shinyServer(function(input, output, session){
output$fwbi <- renderText({
income2<- input$Income
debt2<- input$Debt
bonus2<- input$Bonus
paste("Your fwbi is: ", income2 + debt2 + bonus2)
})
})
Many thanks
If you want to be able to add an arbitrary number of rows to the original data, you can use a reactiveValues list:
Dframe <- data.frame(income = rnorm(5),
debt = rnorm(5),
bonus = rnorm(5))
library(shiny)
shinyApp(
ui =
shinyUI(
fluidPage(
headerPanel("Calculating fwbs"),
sidebarPanel(
sliderInput("Income", "Please Select Income: ", min=0, max=5000,
value=2500, step=100),
sliderInput("Debt", "Please Select Debt: ", min = 0, max=2500,
value=1250, step = 100),
sliderInput("Bonus", "Have you received any bonus: ", min=0, max= 1000,
value=500, step =100),
actionButton(inputId = "btn_add_to_data",
label = "Add To Data")
),
mainPanel(
textOutput("fwbi"),
tableOutput("data")
)
)
),
server =
shinyServer(function(input, output, session){
# Store the original data at start up.
Data <- reactiveValues(
Source = Dframe
)
# Every time you click "Add Data", it will add the user-input to Data$Source
observeEvent(
input$btn_add_to_data,
{
new_row <- data.frame(income = input$Income,
debt = input$Debt,
bonus = input$Bonus)
Data$Source <- rbind(Data$Source,
new_row)
}
)
output$fwbi <- renderText({
income2<- input$Income
debt2<- input$Debt
bonus2<- input$Bonus
paste("Your fwbi is: ",
scale(Data$Source$income) +
scale(Data$Source$debt) +
scale(Data$Source$bonus))
})
output$data <- renderTable({
Data$Source
})
})
)
If you want to limit the user to only adding one row, you can use an eventReactive
Dframe <- data.frame(income = rnorm(5),
debt = rnorm(5),
bonus = rnorm(5))
library(shiny)
shinyApp(
ui =
shinyUI(
fluidPage(
headerPanel("Calculating fwbs"),
sidebarPanel(
sliderInput("Income", "Please Select Income: ", min=0, max=5000,
value=2500, step=100),
sliderInput("Debt", "Please Select Debt: ", min = 0, max=2500,
value=1250, step = 100),
sliderInput("Bonus", "Have you received any bonus: ", min=0, max= 1000,
value=500, step =100),
actionButton(inputId = "btn_add_to_data",
label = "Add To Data")
),
mainPanel(
textOutput("fwbi"),
tableOutput("data")
)
)
),
server =
shinyServer(function(input, output, session){
NewData <- eventReactive(
input$btn_add_to_data,
{
new_row <- data.frame(income = input$Income,
debt = input$Debt,
bonus = input$Bonus)
rbind(Dframe,
new_row)
}
)
output$fwbi <- renderText({
income2<- input$Income
debt2<- input$Debt
bonus2<- input$Bonus
paste("Your fwbi is: ",
scale(NewData()$income) +
scale(NewData()$debt) +
scale(NewData()$bonus))
})
output$data <- renderTable({
NewData()
})
})
)
We can change the codes to
library(shiny)
library(DT
-create a function
fscale <- function(data = NULL) {
ui <- fluidPage(
headerPanel(title = "Calculating fwbs"),
sidebarPanel(
sliderInput("Income", "Please Select Income: ", min=0, max=5000,
value=2500, step=100),
sliderInput("Debt", "Please Select Debt: ", min = 0, max=2500,
value=1250, step = 100),
sliderInput("Bonus", "Have you received any bonus: ", min=0, max= 1000,
value=500, step =100),
numericInput("n", "Number of rows to scale:", 10, min = 1, max = 100)
),
mainPanel(
textOutput("fwbi"),
dataTableOutput("data"))
)
server <- function(input, output, session){
dat_scale <- reactive({
n1 <- seq_len(input$n)
data[["Income"]][n1] <- (data$Income[n1] - input$Income)/data$Income[n1]
data[["Debt"]][n1] <- (data$Debt[n1] - input$Debt)/data$Debt[n1]
data[["Bonus"]][n1] <- (data$Bonus[n1] - input$Bonus)/data$Bonus[n1]
data
})
output$data <- renderDataTable({
dat_scale()
})
output$fwbi <- renderText({
income2<- input$Income
debt2<- input$Debt
bonus2<- input$Bonus
paste("Your fwbi is: ", income2 + debt2 + bonus2)
})
}
shinyApp(ui= ui, server = server)
}
-run the function
fscale(df1)
-output
data
set.seed(24)
df1 <- data.frame(Income = sample(0:5000, 25, replace = TRUE),
Debt = sample(0:2500, 25, replace = TRUE),
Bonus = sample(0:1000, 25, replace = TRUE))

Delay Reaction 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),
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?

Update of the variable by constant in shiny

The community helped me in developing this code
library(shiny)
server <- shinyServer(function(input, output, session) {
values <- reactiveValues()
values$df <- data.frame(N = numeric(0), A = numeric(0), C = numeric(0))
newEntry <- observeEvent(input$update,{
gr <- 10 + input$n
newLine <- isolate(c(input$n, input$nr1, gr))
values$df[nrow(values$df) + 1,] <- c(input$n, input$nr1, gr)
})
output$table1 <- renderTable({values$df})
})
ui <- shinyUI(fluidPage(
titlePanel("submitButton example"),
fluidRow(
column(3, wellPanel(
sliderInput("nr1", "Give a number: ", min = 0, max = 100, value = 0, step = 2),
sliderInput("n", "N:", min = 10, max = 1000, value = 200, step = 10),
actionButton("update", "Update Table"))),
column(6, tableOutput("table1"))
)
))
shinyApp(ui, server)
And I come to a new problem with that.
Now, I'd like that the app do like this: on click on the update, the variable A should always add a 5 i.e. if I have starting value of 5 than on the next click it should be 10 than 15, 20 etc?
Now when I click update the same number appears continously
Is this what you want? Also you dont need the isolate in there.
rm(list = ls())
library(shiny)
ui <- shinyUI(fluidPage(
titlePanel("submitButton example"),
fluidRow(
column(3, wellPanel(
sliderInput("nr1", "Give a number:", min = 1, max = 100, value = 1, step = 1),
sliderInput("n", "N:", min = 10, max = 1000, value = 200, step = 10),
actionButton("update", "Update Table"))),
column(6, tableOutput("table1"))
)
))
server <- shinyServer(function(input, output, session) {
values <- reactiveValues()
values$df <- data.frame(N = numeric(0), A = numeric(0), C = numeric(0))
newEntry <- observeEvent(input$update,{
if(!is.null(input$nr1) & is.null(values$A)){
values$A <- input$nr1
}
if(nrow(values$df) > 0){
values$A <- values$A + 5
}
gr <- 10 + input$n
values$df[nrow(values$df) + 1,] <- c(input$n, values$A, gr)
})
output$table1 <- renderTable({values$df})
})
shinyApp(ui, server)

Resources