I'm using conditionalPanel to create a UI that first presents a panel with options to the user and then displays a tabbed dashboard using tabsetPanel. The simple act of adding another tabPabel as shown below somehow prevents the server.R file from running. I've tested using print statements. It seems like the Shiny app is breaking, but I can't find a syntax error or any reason for it to be.
conditionalPanel(
condition = "output.panel == 'view.data'",
tabsetPanel(id = "type",
tabPanel("Script", value = "script",
fluidPage(
br(),
fluidRow(
column(3, uiOutput("script.name")),
column(3, uiOutput("script.message"))
),
hr(),
plotlyOutput("plotly")
)
),
tabPanel("Location", value = "location",
fluidPage(
br(),
fluidRow(
# column(3, uiOutput("id.range"))
),
hr(),
plotlyOutput("plot")
)
)
# when this tabPanel is uncommented it doesn't work
# ,tabPanel("Accelerometer", value = "accelerometer",
# fluidPage(
# br(),
# hr(),
# plotlyOutput("plot")
# )
# ),
)
)
It's not failing because of the additional tabPanel, it's failing because it contains a duplicate reference to output$plot. Each output of the server function can only be displayed once. For example, this runs, but will fail if the duplicated line is uncommented:
library(shiny)
ui <- shinyUI(fluidPage(
# textOutput('some_text'),
textOutput('some_text')
))
server <- shinyServer(function(input, output){
output$some_text <- renderText('hello world!')
})
runApp(shinyApp(ui, server))
A simple solution is to save the results of the render* function to a local variable, which you can then save to two outputs:
library(shiny)
ui <- shinyUI(fluidPage(
textOutput('some_text'),
textOutput('some_text2')
))
server <- shinyServer(function(input, output){
the_text <- renderText('hello world!')
output$some_text <- the_text
output$some_text2 <- the_text
})
runApp(shinyApp(ui, server))
Related
Is there some way to have a dynamic titlePanel title that pulls directly from UI kind of like below? If it's not possible, is it possible to have a second row that's similar to titlepanel right below titlepanel?
# Define UI ----
ui <- fluidPage(
##Whatever UI code here
titlepanel_text = paste0("Some string", variable_with_text)
)
# Define server logic ----
server <- function(input, output) {
titlePanel("title panel"),
#Rest of server code here
}
Render the text in the server and grab the text output in the UI:
library(shiny)
# Define UI ----
ui <- fluidPage(
##Whatever UI code here
titlePanel(textOutput("title_panel")),
sidebarLayout(
sidebarPanel(),
mainPanel(h1("text"))
)
)
# Define server logic ----
server <- function(input, output) {
output$title_panel <- renderText({
paste0("This is the date/time: ", Sys.time() )
})
}
shiny::shinyApp(ui, server)
you can insert this kind of code to structure your title panel
# Application title
titlePanel(
fixedRow(
column(9,
"My Template",
fixedRow(
column(9,
paste0("Author : ", author)
),
column(3,
paste0("date : ", today(tzone = ""))
)
)
)
) ),
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)
In the attached MWE Shiny example, I have a nested tabsetPanel within a tabPanel for a navbar. If you run the MWE with only one tabPanel within the tabSet you will see that Shiny behaves exactly as it is expected. However, if you run the MWE with two tabPanels, the result is not printed to the main panel of each tab.
Why does this behaviour occur? And how do I resolve this conundrum?
library(shiny)
ui <- shinyUI(navbarPage("tabalicious",
tabPanel("Nav1", value = "nav1",
mainPanel(h2("Hello"),
br(),
p("This is my app.")
)
)
,
tabPanel("Nav2", value = "nav2",
tabsetPanel(
tabPanel("tabsettab1",
sidebarLayout(
sidebarPanel(
helpText("Choose your settings"),
selectInput("zone_type",
label = "Choose a zone type to display",
choices = list("Industrial", "Residential"),
selected = "Industrial")
),
mainPanel(h2("A tab for a tabSet"),
textOutput('zone_type')
)
)
)
# Uncomment this to see the issue
# ,
# tabPanel("tabsettab2",
# sidebarLayout(
# sidebarPanel(
# helpText("Choose your settings"),
# selectInput("zone_type",
# label = "Choose a zone type to display",
# choices = list("Industrial", "Residential"),
# selected = "Industrial")
# ),
# mainPanel(h2("A tab for a tabSet"),
# textOutput('zone_type')
# )
# )
# )
)
)
)
)
server <- shinyServer(function(input, output) {
output$zone_type <- renderText({
paste("You have selected", input$zone_type)
})
})
# Run the application
shinyApp(ui = ui, server = server)
It doesn't have to do with tabs, but multiple calls to output the results of the same render* function. For example, a simplified page (with no tabs) will work fine, but if you uncomment the duplicated call, will fail to display zone_type:
library(shiny)
server <- shinyServer(function(input, output) {
output$zone_type <- renderText({paste("You have selected", input$zone_type)})
})
ui <- shinyUI(fluidPage(
selectInput("zone_type",
label = "Choose a zone type to display",
choices = list("Industrial", "Residential")),
# textOutput('zone_type'),
textOutput('zone_type')
))
runApp(shinyApp(server = server, ui = ui))
While your shinyUI function can only call each output of shinyServer once, within shinyServer you can call the inputs as many times as you like, so it's easy to duplicate outputs:
library(shiny)
server <- shinyServer(function(input, output) {
output$zone_type <- renderText({paste("You have selected", input$zone_type)})
output$zone_type2 <- renderText({paste("You have selected", input$zone_type)})
})
ui <- shinyUI(fluidPage(
selectInput("zone_type",
label = "Choose a zone type to display",
choices = list("Industrial", "Residential")),
textOutput('zone_type'),
textOutput('zone_type2')
))
runApp(shinyApp(server = server, ui = ui))
If you don't want to duplicate work for the server, you can't pass one output to another, but you can just save the render* results to a local variable which you can pass to both outputs:
server <- shinyServer(function(input, output) {
zone <- renderText({paste("You have selected", input$zone_type)})
output$zone_type <- zone
output$zone_type2 <- zone
})
I am trying to use conditionalPanel to display message when a file is being loaded. However, the panel is not disappearing once the condition is TRUE. I have created a reproducible code below:
server.R
library(shiny)
print("Loading start")
print(paste("1->",exists('FGram')))
FGram <- readRDS("data/UGram.rds")
print(paste("2->",exists('FGram')))
print("Loading end")
shinyServer( function(input, output, session) {
})
ui.R
library(shiny)
shinyUI( fluidPage(
sidebarLayout(
sidebarPanel(
h4("Side Panel")
)
),
mainPanel(
h4("Main Panel"),
br(),
textOutput("First Line of text.."),
br(),
conditionalPanel(condition = "exists('FGram')", HTML("PLEASE WAIT!! <br>App is loading, may take a while....")),
br(),
h4("Last Line of text..")
)
)
)
Conditions supplied to conditionalPanel are executed in the javascript environment, not the R environment, and therefore cannot reference or inspect variables or functions in the R environment. A solution to your situation would be to use uiOutput, as in the example below.
myGlobalVar <- 1
server <- function(input, output) {
output$condPanel <- renderUI({
if (exists('myGlobalVar'))
HTML("PLEASE WAIT!! <br>App is loading, may take a while....")
})
}
ui <- fluidPage({
uiOutput('condPanel')
})
shinyApp(ui=ui, server=server)
In my R shiny application, I would like to have one button to submit one set of inputs (which affect one portion of the output) and another one to submit the remaining inputs (which affect a different portion of the output). The code in the widgets example of the Shiny tutorial uses a submitButton but it seems like all the inputs are delivered when that single button is pressed? Thanks in advance for your help.
Here is an example showing actionButtons controlling reactive components:
library(shiny)
runApp(list(
ui = fluidPage(
titlePanel("Hello Shiny!"),
sidebarLayout(
sidebarPanel(
tags$form(
numericInput('n', 'Number of obs', 100)
, br()
, actionButton("button1", "Action 1")
)
, tags$form(
textInput("text", "enter some text", value= "some text")
, br()
, actionButton("button2", "Action 2")
)
),
mainPanel(
plotOutput('plot')
, textOutput("stext")
)
)
),
server = function(input, output) {
output$plot <- renderPlot({
input$button1
hist(runif(isolate(input$n)))
})
output$stext <- renderText({
input$button2
isolate(input$text )
})
}
)
)