Interdependent widgets in Shiny ui - r

I am running the current version of RStudio, R, and all R packages.
In the sample code below, my goal is to set the maximum value for the xcol and ycol so they are limited to the number of columns in the dataframe that is being plotted. The code below results in the error "object 'input' not found." I suspect the problem may be that I am making the widgets in the ui dependent, but that is a guess on my part. Is that the problem, and is there a strategy that I can use to get around it.
I reviewed posts that contained the same error, but couldn't find anything that answered my question (or didn't recognize when it was answered.) The closest posts to my issue were: R Shiny error: object input not found; R Shiny renderImage() does not recognize object 'input'; Error in eval: object 'input' not found in R Shiny app; Conditional initial values in shiny UI?
Here is some reproducible code with random data.
library(tidyverse)
library(cluster)
library(vegan)
library(shiny)
dta <- rnorm(100, mean = 0, sd = 1)
mat <- matrix(dta, nrow = 10)
dm <- daisy(mat, metric = "euclidean") %>% as.matrix()
server <- function(input, output) {
output$plot <- renderPlot({
nmds <- metaMDS(dm, distance = "euclidean", k = input$dim, trymax = 2000, autotransform = FALSE, noshare = FALSE, wascores = FALSE)
df <- nmds$points %>% as.data.frame()
plot(df[,input$xcol], df[,input$ycol])
}, height = 500, width = 500)
}
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
numericInput("dim", "Number of dimensions", value = 2, min = 2, max = 12),
numericInput("xcol", "X column", value = 1, min = 1, max = input$dim),
numericInput("ycol", "Y column", value = 2, min = 1, max = input$dim)
),
mainPanel(
plotOutput("plot")
)
)
)

You can use updateNumericInput to modify the UI from the server:
# Modify ui to use initial max
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
numericInput("dim", "Number of dimensions", value = 2, min = 2, max = 12),
numericInput("xcol", "X column", value = 1, min = 1, max = 2),
numericInput("ycol", "Y column", value = 2, min = 1, max = 2)
),
mainPanel(
plotOutput("plot")
)
)
)
# Modify server to update max when dim changes
# (notice the session parameter needed for updateNumericInput)
server <- function(input, output, session) {
output$plot <- renderPlot({
if(input$xcol>input$dim)
updateNumericInput(session, "xcol", value=input$dim, max=input$dim)
else
updateNumericInput(session, "xcol", max=input$dim)
if(input$ycol>input$dim)
updateNumericInput(session, "ycol", value=input$dim, max=input$dim)
else
updateNumericInput(session, "ycol", max=input$dim)
nmds <- metaMDS(dm, distance = "euclidean", k = input$dim, trymax = 2000, autotransform = FALSE, noshare = FALSE, wascores = FALSE)
df <- nmds$points %>% as.data.frame()
plot(df[,min(input$dim,input$xcol)], df[,min(input$dim,input$ycol)])
}, height = 500, width = 500)
}

Related

how to update a dataset in R shiny

Can I get help on how to get the below code to work? I am looking to update the numbers in
dataExample <- getDataset(n1 = c(20),n2 = c(20), means1 = c(18), means2 = c(9),stds1 = c(14), stds2 = c(14))
based on input values and then generate the plot whenever I apply changes but not sure how to do it. I read it somewhere it says need to use reactive or observe but I am not sure how to modify the code?
library(shiny)
library(plyr)
library(rmarkdown)
library(rpact)
design <- getDesignGroupSequential(kMax = 2, alpha = 0.05, informationRates = c(0.5, 1), typeOfDesign = "WT", deltaWT = 0.5)
ui <- fluidPage(
titlePanel("Efficacy Monitoring Using Conditional Power"),
sidebarLayout(
sidebarPanel(
numericInput('nn1', 'Number of Subjects at Current stage (Active)', 20, min = 1, max = 100),
numericInput('nn2', 'Number of Subjects at Current stage (Control)', 20, min = 1, max = 100),
textInput('Mean1', 'Mean1',"18"),
textInput('Mean2', 'Mean2',"9"),
textInput('SD1', 'SD1',"14"),
textInput('SD2', 'SD2',"14"),
textInput('nPlanned', 'Additional Numbers Planned',"40"),
submitButton(text = 'Apply Changes')
),
# Main panel for displaying outputs ----
mainPanel(plotOutput("plot2")
)
)
)
server <- function(input,output){
dataExample <- getDataset(
n1 = c(20),
n2 = c(20),
means1 = c(18),
means2 = c(9),
stds1 = c(14),
stds2 = c(14)
)
stageResults <- getStageResults(design, dataExample,thetaH0 = 0)
output$plot2<-renderPlot(
plot(stageResults, nPlanned = c(as.numeric(input$nPlanned)), thetaRange = c(0, 20))
)
}
# Run the app ----
shinyApp(ui, server)
Use a reactive function and put the input values
library(shiny)
library(plyr)
library(rmarkdown)
library(rpact)
design <- getDesignGroupSequential(kMax = 2, alpha = 0.05, informationRates = c(0.5, 1), typeOfDesign = "WT", deltaWT = 0.5)
ui <- fluidPage(
titlePanel("Efficacy Monitoring Using Conditional Power"),
sidebarLayout(
sidebarPanel(
numericInput('nn1', 'Number of Subjects at Current stage (Active)', 20, min = 1, max = 100),
numericInput('nn2', 'Number of Subjects at Current stage (Control)', 20, min = 1, max = 100),
# WHY THE CHOICE OF textInput instead of numericInput ?
textInput('Mean1', 'Mean1',"18"),
textInput('Mean2', 'Mean2',"9"),
textInput('SD1', 'SD1',"14"),
textInput('SD2', 'SD2',"14"),
textInput('nPlanned', 'Additional Numbers Planned',"40"),
submitButton(text = 'Apply Changes')
),
# Main panel for displaying outputs ----
mainPanel(plotOutput("plot2")
)
)
)
server <- function(input,output){
# Use the input values in a reactive function
dataExample <- reactive({
getDataset(
n1 = input$nn1,
n2 = input$nn2,
means1 = as.numeric(input$Mean1),
means2 = as.numeric(input$Mean2),
stds1 = as.numeric(input$SD1),
stds2 = as.numeric(input$SD2)
)
})
output$plot2<-renderPlot({
stageResults <- getStageResults(design, dataExample(), thetaH0 = 0)
plot(stageResults, nPlanned = c(as.numeric(input$nPlanned)), thetaRange = c(0, 20))
})
}
# Run the app ----
shinyApp(ui, server)

Error: Object 'X' not found - while deploying random forest model in Shiny

I am trying to deploy a random forest model (model.rds, that was already developed, stored in the same folder) in shiny. However, I ran into the error shown below.
Warning: Error in eval: object 'reports' not found
133: eval
132: eval
131: model.frame.default
129: predict.randomForest
126: <reactive:datasetInput> [/Users/.../app.R#145]
110: datasetInput
97: renderTable [/Users/.../app.R#173]
96: func
83: renderFunc
82: output$tabledata
1: shiny::runApp
Other information, including ui.R (user interface), server.R (server) shown below
First, this is the information I have before getting into the ui.R.
# Import required libraries
library(shiny)
library(shinythemes)
library(data.table)
library(randomForest)
library(AER)
library(flexdashboard)
# Read the random forest built and saved from model.R
model <- readRDS("model.rds") #This is built in model.R and saved as model.rds, which is stored in the same folder
See the code incorporated in the user interface (ui.R)
######### User Interface #############
ui <- fluidPage(
theme = shinytheme("flatly"),
#Page header
headerPanel('Prediction: Probability of Credit Card Approval'),
#Input values
sidebarPanel(
HTML("<h5>Select Input Features</h5>"),
selectInput("owner",
label = "Owner",
choices = list("yes" = "yes", "no" = "no"),
selected = "yes"),
selectInput("selfemp",
label = "Selfemployed",
choices = list("yes" = "yes", "no" = "no"),
selected = "no"),
sliderInput("reports",
label = "Derogatory_Reports",
min = 0,
max = 14,
value = 3),
sliderInput("age",
label = "Age",
min = 1,
max = 84,
value = 33),
sliderInput("income",
label = "Income",
min = 0.2,
max = 14,
value = 3.5),
sliderInput("share",
label = "Share_of_CCard_Exp_to_Yrly_Inc",
min = 0,
max = 1,
value = 0.10),
sliderInput("expenditure",
label = "Avg_Mthly_CCard_Expenditure",
min = 0,
max = 3100,
value = 185),
sliderInput("dependents",
label = "No_of_Dependents",
min = 0,
max = 6,
value = 2),
sliderInput("months",
label = "Months_Living_at_Current_Address",
min = 0,
max = 540,
value = 56),
sliderInput("majorcards",
label = "No_of_Major_CCards_held",
min = 0,
max = 1,
value = 0.8),
sliderInput("active",
label = "No_of_Active_Credit_Accounts",
min = 0,
max = 46,
value = 7),
actionButton("submitbutton", "Submit", class = "btn btn-primary")
#submitButton("Submit")
),
mainPanel(
tags$label(h3('Status of Credit Card Application')),
verbatimTextOutput('contents'),
tableOutput('tabledata')#, # Prediction results table
)
)
Information of the code in the server.R is shown below
######### Server #####################
server <- function(input, output, session) {
#Input data
datasetInput <- reactive({
df <- data.frame(
Name = c("Owner",
"Selfemployed",
"Derogatory_Reports",
"Age",
"Income",
"Share_of_CCard_Exp_to_Yrly_Inc",
"Avg_Mthly_CCard_Expenditure",
"No_of_Dependents",
"Months_Living_at_Current_Address",
"No_of_Major_CCards_held",
"No_of_Active_Credit_Accounts"
),
Value = as.character(c(input$owner,
input$selfemp,
input$reports,
input$age,
input$income,
input$share,
input$expenditure,
input$dependents,
input$months,
input$majorcards,
input$active
)),
stringsAsFactors = FALSE)
card <- 0
df <- rbind(df, card)
input <- transpose(df)
write.table(input, "input.csv", sep = ",", quote = FALSE, row.names = FALSE, col.names = FALSE)
test <- read.csv(paste("input", ".csv", sep=""), header = TRUE)
Output <- data.frame(Prediction = predict(model,test), round(predict(model, test, type = "prob"), 3))
print(Output)
})
#my_plot <- reactive({
# gauge(datasetInput()$Yes, min = 0, max = 100, symbol = '%', label = "Approval", gaugeSectors(
# success = c(80,100), warning = c(40, 79), danger = c(0, 39)
# ))
#})
#datasetInput()
#output$Scale <- renderGauge({
# my_plot()
#})
# Probability Text Box
output$contents <- renderPrint({
if (input$submitbutton>0) {
isolate("Decision Made.")
} else {
return("Click SUBMIT After Selecting the Values of Features")
}
})
# Prediction results table
output$tabledata <- renderTable({
if (input$submitbutton>0) {
isolate(datasetInput())
}
})
}
######## Create the shiny app #########
shinyApp(ui = ui, server = server)
Please let me know if you have any solutions. I have been trying other similar questions but did not work any solutions.
I was expecting to run the random forest model and give me a table showing the predictions of the dependent variable but instead the following error is shown in the app after selecting the features and clicking the submit button.
Error: object 'X' not found

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)

Topic Modelling Visualization using LDAvis and R shinyapp and parameter settings

I am using LDAvis in R shiny app.
Here is the code and it works without errors.
# docs is a csv file with a "text" column, e.g.
# docs <- read.csv("docs.csv",sep=",",header=TRUE)
ui <- navbarPage(
title = "NLP app",
tabPanel("Topic Model",icon = icon("group"),
fluidPage(
headerPanel(""),
titlePanel(p(h2("Topic Modelling example",style = "color:#4d3a7d"))),
#sidebarPanel(
wellPanel(tags$style(type="text/css", '#leftPanel { width:200px; float:left;}'), style = "background: lightgrey",
id = "leftPanel",
sliderInput("nTopics", "Number of topics to display", min = 5, max = 50, value = 10, step=5),
sliderInput("nTerms", "#top terms per topic", min = 10, max = 50, value = 20, step=5),
tags$hr(),
actionButton(inputId = "GoButton", label = "Go", icon("refresh"))
),
mainPanel(
tabPanel("Topic Visualisation", hr(),helpText(h2("Please select a topic!")), visOutput('visChart')))
)
)
)
# server
server <- function(input, output, session) {
Topic_Subset <- reactive({
docs <- docs$text
nTopics <- input$nTopics
# topic model using text2vec package
tokens = docs %>%
tolower %>%
word_tokenizer
it = itoken(tokens, progressbar = FALSE)
v = create_vocabulary(it,stopwords=tm::stopwords("en"))
vectorizer = vocab_vectorizer(v)
dtm = create_dtm(it, vectorizer, type = "dgTMatrix")
lda_model = text2vec::LDA$new(n_topics = nTopics, doc_topic_prior = 0.1, topic_word_prior = 0.01)
lda_model$fit_transform(x = dtm, n_iter = 1000,
convergence_tol = 0.001, n_check_convergence = 25,
progressbar = FALSE)
return(lda_model) #
})
output$visChart <- renderVis({
input$GoButton
isolate({
nterms <- input$nTerms
lda_model <- Topic_Subset()
})
lda_model$plot(out.dir = "./results", R = nterms, open.browser = FALSE)
readLines("./results/lda.json")
})
}
shinyApp(ui = ui, server = server)
I would like to see whether it is possible to use width = "80%" in visOutput('visChart') similar to, for example, wordcloud2Output("a_name",width = "80%"); or any alternative methods to make the size of visualization smaller. Particularly, when I minimize the shiny app window, the plot does not fit in the page. My second question is: how can I initialize the parameter lambda (please see the below image and yellow highlights) with another number like 0.6 (not 1)?

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)

Resources