I just new in Shiny, and i have problem. i have a event reactive and the stop function inside. when I run my code(no checkbox and do click button), the shiny is work well. but in console display the error message "eventReactiveHandler". do you have a solution for my problem? i want to no error message in my console.
and i not expect the solution is
opt <- options(show.error.messages=FALSE)
on.exit(options(opt))
because the error will not display in my all code, i want just specifically in this error.
thank you... this is the code...
rm(list = ls())
library(shiny)
library(shinyBS)
var.x<-reactiveValues()
shinyApp(
ui =
fluidPage(
sidebarLayout(
sidebarPanel(
checkboxGroupInput("indepvar","Independent Variable",
choices = c("1"=1,"2"=2)),
actionButton("tabBut", "View Table")
),
mainPanel(
uiOutput("coba"),
uiOutput("popup4")
)
)
),
server =
function(input, output, session) {
output$coba <- renderUI({
gendata()
indep<-NULL
for(i in 1:length(var.x)){
indep <- paste(indep,var.x[i],",")
}
list(
renderText(indep)
)
})
gendata<- eventReactive(input$tabBut,{
if(is.null(input$indepvar)){
stop()
}
var.x<<- input$indepvar
})
output$popup4 <- renderUI({
if(!is.null(input$indepvar))return()
list(
bsModal("modalExample4", "Peringatan", "tabBut", size = "small",wellPanel(
"Anda belum memilih independent variabel..."
))
)
})
}
)
I wouldn't advise suppressing error messages, as there are in there for you, I suggest you look into validate and need in shiny, you can go read validation article
To quickfix you issue you can just return NULL
rm(list = ls())
library(shiny)
library(shinyBS)
var.x<-reactiveValues()
shinyApp(
ui =
fluidPage(
sidebarLayout(
sidebarPanel(
checkboxGroupInput("indepvar","Independent Variable",
choices = c("1"=1,"2"=2)),
actionButton("tabBut", "View Table")
),
mainPanel(
uiOutput("coba")
)
)
),
server =
function(input, output, session) {
output$coba <- renderUI({
gendata()
indep<-NULL
for(i in 1:length(var.x)){
indep <- paste(indep,var.x[i],",")
}
list(
renderText(indep)
)
})
gendata<- eventReactive(input$tabBut,{
if(is.null(input$indepvar)){
var.x <<- NULL
return(NULL)
stop()
}
var.x<<- input$indepvar
})
}
)
You need to do two things as per the code below:
Make sure that gendata returns nothing when there are no independent variables selected (see lines 37-40). This stops your original error message
Make sure that output$coba is not evaluated when gendata has no value (see line 25)
Hope this helps,
John
rm(list = ls())
library(shiny)
library(shinyBS)
var.x<-reactiveValues()
shinyApp(
ui =
fluidPage(
sidebarLayout(
sidebarPanel(
checkboxGroupInput("indepvar","Independent Variable",
choices = c("1"=1,"2"=2)),
actionButton("tabBut", "View Table")
),
mainPanel(
uiOutput("coba"),
uiOutput("popup4")
)
)
),
server =
function(input, output, session) {
output$coba <- renderUI({
req(gendata())
indep<-NULL
for(i in 1:length(var.x)){
indep <- paste(indep,var.x[i],",")
}
list(
renderText(indep)
)
})
gendata<- eventReactive(input$tabBut,{
if(is.null(input$indepvar)) {
var.x <<- NULL
return()
}
var.x<<- input$indepvar
})
output$popup4 <- renderUI({
if(!is.null(input$indepvar))return()
list(
bsModal("modalExample4", "Peringatan", "tabBut", size = "small",wellPanel(
"Anda belum memilih independent variabel..."
))
)
})
}
)
Related
I am trying to build a shiny app where with a click of a button 6 codes gets executed. since the processing time is 5-10 mins, to keep the users aware of the process, I want to have a textbox/verbatim box that will change basis which code is run.
"error in evaluating the argument 'x' in selecting a method for function 'head': object 'x' not found"
Edit : Have changed the code. However the first instance of text is not displayed "data loading".
TIA.
library(shinyjs)
library(shiny)
ui <- fluidPage(
titlePanel("Testing Textupdate Multiple Times"),
sidebarLayout(
sidebarPanel(
useShinyjs(),
actionButton("button1","Click"),
textInput("text1", label = "", value = ""),
dataTableOutput("table1")
),
mainPanel(
)
))
server = function(input, output,session) {
x<-data.frame()
observeEvent(input$button1, {
updateTextInput(session,"text1",value = "Data Loading")
withProgress(message = 'Data Loading',
detail = 'This may take a while...', value = 0, {
for (i in 1:10) {
incProgress(1/10)
Sys.sleep(0.25)
}
})
x<-mtcars
updateTextInput(session,"text1",value = "Data Loaded")})
output$table1 <- renderDataTable({
head(x)})
}
shinyApp(ui, server)
The updateTextInput will not be implemented until the end of the observeEvent, so the "Data Loading" message will not be seen. However, you can try a sendCustomMessage and add javascript to show the text instead. Here is a working example that uses verbatimTextOutput instead of a textInput. Please let me know if this works for you - I hope it is helpful.
library(shiny)
ui <- fluidPage(
tags$script('
Shiny.addCustomMessageHandler("status_text", function(text) {
document.getElementById("text1").innerHTML = text;
})
'),
titlePanel("Testing Textupdate Multiple Times"),
sidebarLayout(
sidebarPanel(
useShinyjs(),
actionButton("button1", "Click"),
verbatimTextOutput("text1")
),
mainPanel(
dataTableOutput("table1")
)
)
)
server = function(input, output, session) {
x <- mtcars
observeEvent(input$button1, {
session$sendCustomMessage("status_text", "Data loading...")
withProgress(message = 'Data Loading',
detail = 'This may take a while...', value = 0, {
for (i in 1:10) {
incProgress(1/10)
Sys.sleep(0.25)
}
})
session$sendCustomMessage("status_text", "Data loaded")
})
output$table1 <- renderDataTable({
head(x)
})
}
shinyApp(ui, server)
If you want the verbatimTextOutput to be present initially (but without text) you can add this to server:
output$text1 <- renderText({
" "
})
I would like to render the bar plots stored in "Plotlist" through the shiny app. I am new to Shiny and request help regarding it. The code:
o<-list()
for(i in 1:10){
Z3<-seq(1+i,10+i,1)
o<-append(o,list(Z3))
}
Plotlist <- vector(mode = "list", 10)
for(i in 1:10){
s<-barplot(o[[i]],names.arg = paste("A",1:10,sep = "_"),main=paste("Plot",i))
Plotlist[[i]]<-recordPlot()
}
library(shiny)
ui<-fluidPage(titlePanel("Plots in a list"),
sidebarPanel(selectInput("plot", "Choose Plot:", choices=paste("Plot",1:10)),hr(),helpText("Trial Plots"),
mainPanel(plotOutput("BARPLOT"))))
server<-function(input, output) {
output$BARPLOT<-renderPlot(for(i in 1:10){Plotlist[[i]]})
}
shinyApp(ui,server)
Found a solution, Thank you Abdessabour Mtk
choices = 1:10
names(choices) <- paste("Plot",1:10)
shinyApp(
ui = fluidPage(
titlePanel("Plots in a list"),
sidebarPanel(
selectInput("plot", "Choose plot:", choices=choices),
hr(),
helpText("Trail plots")),
plotOutput("barplot")
),
server = function(input, output) {
output$barplot<-renderPlot({
i<- as.integer(input$plot)
Plotlist[[i]]
})
}
)
In order to print the specified plot you need access the selected value of selectinput inside the renderplot this is done by adding {i<-input$plot} where plot is the name of the input
choices = 1:10
names(choices) <- paste("Plot",1:10)
shinyApp(
ui = fluidPage(
titlePanel("Plots in a list"),
sidebarPanel(
selectInput("plot", "Choose Plot:", choices=choices),
hr(),
helpText("Trial Plots")),
plotOutput("barplot")
),
server = function(input, output) {
output$barplot<-renderPlot({
i<- as.integer(input$plot)
barplot(o[[i]],names.arg = paste("A",1:10,sep = "_"),main=paste("Plot",i))
}, width=400)
}
)
Is there any way to render HTML in shiny's validation messages? I tried different approaches using the HTML wrapper, the tags$... functions, as well as a separate htmlOutput for the validation message, but could not get any of them to work. Here is a simple example app that shows this issue - the select should be bold in the validation message but the HTML tags are escaped (contrived example, I know, but hopefully conveys the idea, I would primarily like to use this to include fa icons in the messages):
runApp(
list(
ui = fluidPage(
titlePanel("Validation App"),
sidebarLayout(
sidebarPanel(
selectInput("data", label = "Data set", choices = c("", "mtcars"))
),
mainPanel(tableOutput("table"))
)
),
server = function(input, output) {
data <- reactive({
# validate test
validate(
need(input$data != "", HTML("Please <strong>select</strong> a data set"))
)
get(input$data, 'package:datasets')
})
output$table <- renderTable(head(data()))
}
)
)
The simplest solution is to use a uiOutput and inside the renderUI function put an if to validate the input. In the code below is an example using HTML and tags$... functions. You can can also put an icon.
library(shiny)
runApp(
list(
ui = fluidPage(
titlePanel("Validation App"),
sidebarLayout(
sidebarPanel(
selectInput("data", label = "Data set", choices = c("", "mtcars"))
),
mainPanel(uiOutput("tableUI"))
)
),
server = function(input, output) {
data <- reactive({
get(input$data, 'package:datasets')
})
output$tableUI <- renderUI({
if (input$data == "") {
div(
HTML("Please <strong>select</strong> a data set"),
tags$p(icon("exclamation"), "Please",tags$strong("select"), "a data set")
)
} else {
tableOutput("table")
}
})
output$table <- renderTable(head(data()))
}
)
)
I'm trying to create the scenario whereby using conditionalpanel, I am able to have an user input of checked boxes to display either 1 or 2 plots, one after another.
My reproducible code can be found below, however, I am unable to display the plots.
Could someone please share with me where did I make a mistake?
library(shiny)
ui = fluidPage(
titlePanel("Plot1 or Plot2?"),
sidebarLayout(
sidebarPanel(
checkboxGroupInput("my_choices", "Plot1 or Plot2",choices = c("Plot1", "Plot2"), selected = "Plot1"),width=2),
mainPanel(
conditionalPanel(
condition = "input.my_choices == 'Plot1'",
plotOutput("plot1")
),
conditionalPanel(
condition = "input.my_choices == 'Plot2'",
plotOutput("plot2")
),
conditionalPanel(
condition = "input.my_choices.includes('Plot1', 'Plot2')",
plotOutput("plot1"),
plotOutput("plot2")
)
)
)
)
server = function(input, output) {
output$plot1 <- renderPlot({plot(iris)})
output$plot2 <- renderPlot({plot(mtcars)})
}
shinyApp(ui, server)
Update:
I've got what I wanted but without using ConditionalPanel function. Here's the code below:
Would appreciate if someone can share with me the proper way of using ConditionalPanel Function! (:
library(shiny)
#data
df <- iris
#ui
ui <- fluidPage(
sidebarPanel(
checkboxGroupInput(inputId = "Question",
label = "Choose the plots",
choices = c("Plot1", "Plot2", "Plot3"),
selected = "")),
mainPanel(
uiOutput('ui_plot')
)
)
#server
server <- function(input, output)
{
# gen plot containers
output$ui_plot <- renderUI({
out <- list()
if (length(input$Question)==0){return(NULL)}
for (i in 1:length(input$Question)){
out[[i]] <- plotOutput(outputId = paste0("plot",i))
}
return(out)
})
# render plots
observe({
for (i in 1:3){
local({ #because expressions are evaluated at app init
ii <- i
output[[paste0('plot',ii)]] <- renderPlot({
if ( length(input$Question) > ii-1 ){
return(plot(runif(100)))
}
NULL
})
})
}
})
}
shinyApp(ui, server)
I would give you an alternative as you will need to create new plots with different id in order for that to work. The simplest one I can think of is using shinyjs package and its hide and show functions. You can also do this via renderUI but you shouldn't give unnecessary work to your server only if you're showing and hiding the elements
library(shiny)
library(shinyjs)
ui = fluidPage(
useShinyjs(),
titlePanel("Plot1 or Plot2?"),
sidebarLayout(
sidebarPanel(
checkboxGroupInput("my_choices", "Plot1 or Plot2",choices = c("Plot1", "Plot2"), selected = "Plot1"),width=2),
mainPanel(
plotOutput("plot1"),
plotOutput("plot2")
)
)
)
server = function(input, output,session) {
# hide plots on start
hide("plot1");hide("plot2")
output$plot1 <- renderPlot({plot(iris)})
output$plot2 <- renderPlot({plot(mtcars)})
observeEvent(input$my_choices,{
if(is.null(input$my_choices)){
hide("plot1"); hide("plot2")
}
else if(length(input$my_choices) == 1){
if(input$my_choices == "Plot1"){
show("plot1");hide("plot2")
}
if(input$my_choices == "Plot2"){
hide("plot1");show("plot2")
}
}
else{
if(all(c("Plot1","Plot2") %in% input$my_choices)){
show("plot1");show("plot2")
}
}
},ignoreNULL = F)
}
shinyApp(ui, server)
I am pretty new to Shiny and dealing with the following problem, upon pressing an actionButton in shiny, I want it to do multiple calculations. I use the handler of observeEvent.
An example:
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(`
actionButton("calc","calculate stuff")),
mainPanel(
textOutput("result")
)
)
)
server <- function(input,output){
observeEvent(input$calc, {output$result <- renderText({"only this is not enough"}) })
}
shinyApp(ui,server')`
Now what I would want is where the output$result is made in the server-observeEvent, I would like to perform additional tasks, say assign a variable a <- 12, calculate B4 <- input$ID1*inputID2 etc.
This can not be hard I imagine.. but I am just not getting there.
kind regards,
Pieter
You can use isolate, see this example:
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
numericInput(inputId = 'x', label = 'Select a value for x', value = 1),
actionButton( "calc", "calculate stuff" )
),
mainPanel(
textOutput("result")
)
)
)
server <- function(input, output) {
output$result <- renderText({
input$calc
isolate({
y<- input$x *2
paste("The result is:", y)
})
})
}
shinyApp(ui, server)