This is a reproducible example. I'm trying to understand using the conditionalpanel function under shiny.
How do I tweak the code in a manner such that when I check both checkboxes, the plot and image will be rendered together? (with the plot on the top and image at the bottom on main panel)
library(shiny)
ui = fluidPage(
titlePanel("Plot or Example?"),
sidebarLayout(
sidebarPanel(
checkboxGroupInput("my_choices", "Example or Plot",choices = c("Plot", "Example"), selected = 1),width=2),
mainPanel(
conditionalPanel(
condition = "input.my_choices == 'Plot'",
plotOutput('my_test1')
),
conditionalPanel(
condition = "input.my_choices == 'Example'",
uiOutput("my_test2")
)
)
)
)
server = function(input, output) {
output$my_test1 <- renderPlot({plot(runif(100))})
output$my_test2 <- renderUI({
images <- c("http://www.i2symbol.com/images/abc-123/o/white_smiling_face_u263A_icon_256x256.png")
tags$img(src= images)
})
}
There are several things to do.
First, your selected argument of checkboxGroupInput should match one of the choices. Here I changed it to "Plot".
Second, I used "input.my_choices.includes('Example') && input.my_choices.includes('Plot')" as the condition when both are selected.
Third, Shiny doesn't allow the same output to be used more than once. To get around that, I made duplicates of the outputs in the server code, and referenced the duplicated names in the conditional Panel for the condition both boxes are checked.
library(shiny)
ui = fluidPage(
titlePanel("Plot or Example?"),
sidebarLayout(
sidebarPanel(
checkboxGroupInput("my_choices", "Example or Plot",choices = c("Plot", "Example"), selected = "Plot"),width=2),
mainPanel(
conditionalPanel(
condition = "input.my_choices == 'Plot'",
plotOutput("my_test1")
),
conditionalPanel(
condition = "input.my_choices == 'Example'",
uiOutput("my_test2")
),
conditionalPanel(
condition = "input.my_choices.includes('Example') && input.my_choices.includes('Plot')",
plotOutput("my_test1a"),
uiOutput("my_test2a")
)
)
)
)
server = function(input, output) {
output$my_test1 <- output$my_test1a <- renderPlot({plot(runif(100))})
output$my_test2 <- output$my_test2a <- renderUI({
images <- c("http://www.i2symbol.com/images/abc-123/o/white_smiling_face_u263A_icon_256x256.png")
tags$img(src= images)
})
}
shinyApp(ui, server)
Related
I found the following code that creates an RShiny app that allows users to visualize a data table based on certain columns that they select. See following code (should run on it's own):
library(shiny)
library(ggplot2) # for the diamonds dataset
ui <- fluidPage(
title = "Examples of DataTables",
sidebarLayout(
sidebarPanel(
conditionalPanel(
'input.dataset === "diamonds"',
checkboxGroupInput("show_vars", "Columns in diamonds to show:",
names(diamonds), selected = names(diamonds))
)
),
mainPanel(
tabsetPanel(
id = 'dataset',
tabPanel("diamonds", DT::dataTableOutput("mytable1")),
)
)
)
)
server <- function(input, output) {
# choose columns to display
diamonds2 = diamonds[sample(nrow(diamonds), 1000), ]
output$mytable1 <- DT::renderDataTable({
DT::datatable(diamonds2[, input$show_vars, drop = FALSE])
})
}
shinyApp(ui, server)
My question is, how can I change this dataset to be reactive, such that instead of always using the diamonds dataset, a data table would result based on what dataset I select from a dropdown menu? Such as adding a selectInput() argument?
If you are just trying to have different tables show based on a selectInput(), then this will work for a small number of tables. Essentially, the output table is an if else statement, which displays a different table depending on what's selected in the selectInput().
library(shiny)
library(ggplot2) # for the diamonds dataset
ui <- fluidPage(
title = "Examples of DataTables",
sidebarLayout(
sidebarPanel(
selectInput("Datasetchoice", "Dataset", choices = c("diamonds", "iris", "mtcars")), #Choose which dataset to display
conditionalPanel(
'input.dataset === "diamonds"',
checkboxGroupInput("show_vars", "Columns in diamonds to show:",
names(diamonds), selected = names(diamonds))
)
),
mainPanel(
tabsetPanel(
id = 'dataset',
tabPanel("diamonds", DT::dataTableOutput("mytable1"))
)
)
)
)
server <- function(input, output) {
# choose columns to display
diamonds2 = diamonds[sample(nrow(diamonds), 1000), ]
output$mytable1 <- DT::renderDataTable({
if(input$Datasetchoice == "diamonds") { #If else statement, show a different table depending on the choice
DT::datatable(diamonds2[, input$show_vars, drop = FALSE])
} else if (input$Datasetchoice == "iris") {
DT::datatable(iris)
} else if(input$Datasetchoice == "mtcars") {
DT::datatable(mtcars)
}
})
}
shinyApp(ui, server)
Here is a solution that updates the checkboxes and the table upon selection of a different dataset. No limit on the number of datasets. But the datasets must be dataframes.
library(shiny)
library(datasets) # for the datasets
ui <- fluidPage(
title = "Examples of DataTables",
sidebarLayout(
sidebarPanel(
selectInput("dat",
label = "Choose data",
choices = c("cars", "mtcars", "faithful", "iris", "esoph", "USArrests")),
checkboxGroupInput("datavars", "Columns to show",
choices = NULL,
selected = NULL)
),
mainPanel(
tabsetPanel(
id = 'dataset',
tabPanel("dataset", DT::dataTableOutput("mytable1")),
)
)
)
)
server <- function(input, output, session) {
r <- reactiveValues(
dataobj = NULL
)
observeEvent(input$dat, {
dataobj <- r$dataobj <- get(input$dat, 'package:datasets')
datavars <- names(dataobj)
freezeReactiveValue(input, "datavars")
updateCheckboxGroupInput(session, "datavars",
choices = datavars,
selected = datavars)
})
output$mytable1 <- DT::renderDataTable({
req(r$dataobj, input$datavars)
DT::datatable(r$dataobj[, input$datavars, drop = FALSE])
})
}
shinyApp(ui, server)
I am trying to read data and if the data has observation , the further UI has to expand. But the conditional Pannel is not working .
Here is the part of the UI and server code.
UI Code:
tabPanel("DMC 1.1", fluid = TRUE, useShinyjs(),
column(width=12,wellPanel(div(style = 'height:120px;',
fluidRow(column(width=9,style = "font-size: 12px;",fileInput("analysis_data2", label = "Import data", accept = c(".csv",".sas7bdat",".xls",".xpt"))))
)),
conditionalPanel(condition = "output.dataUpload", wellPanel(fluidRow(
column(width=5,textInput("subset","Subsettign Condition",value="")),
column(width=5,textInput("byvar","By Variable",value="")),
column(width=5,textInput("subgrp","SubGroup Variable",value="")),
column(width=5,textInput("trtvar","Treatment Variable",value="")),
column(width=5,textInput("xaxisvar","X Axis Variable",value="")),
column(width=5,textInput("yaxisvar","Y Axis Variable",value=""))
)))
)
)
Server Code:
#################Tab 2 - DMC 2.0#########################
analysis_d <- reactive({data_read(datain=input$analysis_data2)})
output$dataUpload <- reactive({return(!is.null(isolate(analysis_d())))})
outputOptions(output, 'dataUpload', suspendWhenHidden=FALSE)
This app will make an additional text input files available in the UI if the uploaded csv file contains at least one row:
library(shiny)
ui <- fluidPage(
fileInput("file", "File"),
conditionalPanel(
condition = "output.available",
textInput("additional_input", "additional input")
)
)
server <- function(input, output, session) {
data <- reactive(read.csv(input$file$datapath))
output$available <- reactive(nrow(data()) >= 1)
outputOptions(output, "available", suspendWhenHidden = FALSE)
}
shinyApp(ui, server)
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'd like to know if there is a way to use an input in the UI component.
This is my sample code:
shinyApp(
ui <- fluidPage(
column(12,fluidRow(column(4, inputPanel(
selectInput("dx", label = "Diagnosis:",
choices = DX, selected = "LOW BACK PAIN")
))
)),
lapply(unique(allProc[dx.x==input$dx])$pat), function(patient) {
fluidRow(column(1, tags$p(patient)),
column(11, lapply(unique(allProc[pat == patient & dx.x == input$dx])$Clinic),
function(clinic){
fluidRow(column(1, tags$p(clinic)),
column(10, plotOutput(outputId = paste(patient, clinic), height = "100%")))
})))
})
),
server <- function(input, output) {
plot
)
Obviously this is wrong.. I can't just do allProc[dx.x==input$dx]), but the idea is the same. How would I filter in the UI component an element user selects in the same component?
TIA!
I'm trying to create a web app where a user can input some data and have it analyzed. If the user doesn't want to upload data and would rather see an example, I want to display an image rather than a plot. Is there a way to decide when to use renderPlot and renderImage based on user input? My solution so far is:
(in my ui.R inside of a fluid page):
conditionalPanel(
condition = "output.useExample == true",
imageOutput("allPCA.image")
),
conditionalPanel(
condition = "output.useExample == false",
plotOutput("allPCA.plot")
)
And I have two functions in my output:
output$allPCA.image <- renderImage({
list(src = "./static/pca.all.png",
contentType = 'image/png',
alt = "Example PCA")
}, deleteFile=FALSE)
output$allPCA.plot <- renderPlot({
plot(stuff))}
Is there a way to do this?
Following an answer for this example renderImage NOT DISPLAYING - R Shiny (only alt text) You can do the following:
rm(list = ls())
library(shiny)
runApp(list(
ui = fluidPage(
titlePanel("Plot or Example?"),
sidebarLayout(
sidebarPanel(
selectInput("my_choices", "Example or Plot",choices = c("Plot", "Example"), selected = 1),width=2),
mainPanel(
conditionalPanel(
condition = "input.my_choices == 'Plot'",
plotOutput('my_test1')
),
conditionalPanel(
condition = "input.my_choices == 'Example'",
uiOutput("my_test2")
)
)
)
),
server = function(input, output) {
output$my_test1 <- renderPlot({plot(runif(100))})
output$my_test2 <- renderUI({
images <- c("http://www.i2symbol.com/images/abc-123/o/white_smiling_face_u263A_icon_256x256.png")
tags$img(src= images)
})
}
))