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)
Related
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)
}
)
I want to generate a boxPlus around my DT-Output. Now when I start my APP, the frame of the box is already there. How do I manage that the box is only displayed when the tableoutput is finished? As input I use a text input.
In my UI I use for the Input:
textInput("name", "Insert Number:")
the final box I create with:
uiOutput("box")
On Serverside I do:
output$name <- renderText(input$name)
New_input <- reactive({
list(input$name)
})
and the box I create like this:
output$box <- renderUI({
boxPlus(
div(style = 'overflow-x: scroll;'), dataTableOutput("table")
)
})
I tried it with: Similar Problem but I can not resolve the problem. Without the box everything works fine.
Never use reactive expressions inside a renderText function.
You have to wrap tagList around your two elements to return a SINGLE element (a list in your case).
Here is a reproduceable example.
library(shiny)
library(shinydashboardPlus)
library(dplyr)
# Define UI for application that draws a histogram
ui <- fluidPage(
# Application title
titlePanel("Hide box"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
textInput("name", "Insert Number to filter cyl:")
),
mainPanel(
uiOutput("box")
)
)
)
server <- function(input, output) {
resultdf <- reactive({
mtcars %>%
filter(cyl > input$name)
})
output$box <- renderUI({
output$table <- renderDataTable({
resultdf()
})
if(input$name == "") {
return(NULL)
} else {
return(
tagList(
boxPlus(
div(style = 'overflow-x: scroll;'), dataTableOutput("table")
)
)
)
}
})
}
# Run the application
shinyApp(ui = ui, server = server)
I am learning R and shiny and have been trying to play around with some of the code from the shiny package documentation here. I have been trying to figure out why the conditional I have added is not responding to my condition.
What am I doing wrong as I do not get an error?
ui <- fluidPage(
uiOutput("ex")
)
server <- function(input, output) {
output$ex <- renderUI({
tagList(
selectInput("n","Please Select :",
choices = c("N","U","T")),
conditionalPanel(condition = "n"=="N",
textInput("inmean"," Mean:",0.25),
textInput("invsd","Sd", 0.02)),
conditionalPanel(condition = "n"== "U",
textInput("inmean","Mean:",0.25),
textInput("insd","Sd", 0.02))
)
})
}
shinyApp(ui, server)
Personally I wouldn't do it this way. I would use an observe({}) statement looking at the input of "n" and use updateTextInput() to change the value.
But this seems to work with the method you're using:
ui <- fluidPage(
selectInput("n","Please Select :",
choices = c("N","U","T")),
uiOutput('ex')
)
server <- function(input, output) {
output$ex <- renderUI({
if(input$n == 'N'){
tagList(
textInput("inmean"," Mean:",0.25),
textInput("invsd","Sd", 0.02)
)
}else if(input$n == 'U'){
tagList(
textInput("inmean","Mean:",0.2),
textInput("insd","Sd", 0.01)
)
}
})
}
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)
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..."
))
)
})
}
)