This code gives me one tab. I would like to be able to add more tabs to it to make some plots, use the aggregate function may be. I tired to add a second tabPanel( object inside my tabsetPanel( but did not work.
I will be obliged if someone could help me with this
library(shiny)
library(dplyr)
ui <- fluidPage(
tabsetPanel(
tabPanel("Table", fluid = TRUE,
sidebarLayout(position = "left",
sidebarPanel("sidebar panel",
selectInput(inputId = "table",
label = "Choose a Supplier",
"Names"),
actionButton(inputId = "btn",label="Update")
),
mainPanel("main panel",
tableOutput("myTable")
)))
))
server <- function(input, output,session)
{
GlassSupplier <- c('Supplier 1','Supplier 2','Supplier 1','Supplier 4','Supplier 2')
WindowType <- c('Wood','Vinyl','Aluminum','Aluminum','Vinyl')
BreakageRate <- c(7.22,6.33,3.63,2,6)
df<- data.frame(GlassSupplier,WindowType,BreakageRate)
data <- eventReactive(input$btn, {
req(input$table)
df %>% dplyr::filter(GlassSupplier %in% input$table) %>%
group_by(WindowType) %>%
dplyr::summarise(BrkRate = mean(BreakageRate))
})
#Update SelectInput Dynamically
observe({
updateSelectInput(session, "table", choices = df$GlassSupplier)
})
output$myTable = renderTable({
data()
})
}
shinyApp(ui,server)
Think of tabsetPanel as any other slider/button, you can insert it inside the sidebar, in the main panel, or before the sidebarLayout.
code for ui:
u <- shinyUI(fluidPage(
titlePanel("title panel"),
sidebarLayout(position = "left",
sidebarPanel("sidebar panel",
selectInput(inputId = "table",
label = "Choose a Supplier",
"Names"),
actionButton(inputId = "btn",label="See Table"),
checkboxInput("donum1", "Make #1 plot", value = T),
checkboxInput("donum2", "Make #2 plot", value = F),
checkboxInput("donum3", "Make #3 plot", value = F),
checkboxInput("donum4", "Make #4 plot", value = F),
sliderInput("wt1","Weight 1",min=1,max=10,value=1),
sliderInput("wt2","Weight 2",min=1,max=10,value=1),
sliderInput("wt3","Weight 3",min=1,max=10,value=1),
sliderInput("wt4","Weight 4",min=1,max=10,value=1)
),
mainPanel("main panel",
tabsetPanel(
tabPanel("Plot", column(6,plotOutput(outputId="plotgraph", width="500px",height="400px"))),
tabPanel('Table', tableOutput("myTable")))
))))
Related
How can I create nested tabs in RShiny like the image below?
Where "Sales Performance" is the parent tab and "Open Quotes - LW" is the sub tab that rolls up under the "Sales Performance Tab"
I have a reproducible example using the iris dataset
library(shiny)
library(DT)
ui <- fluidPage(
titlePanel("Tabsets"),
sidebarLayout(
sidebarPanel(
textInput('search', "Search"),
),
mainPanel(
tabsetPanel(id = "tabsetPanelID",
type = "tabs",
tabPanel("Tab1", DTOutput('DT1')),
tabPanel("Tab2", DTOutput('DT2')),
tabPanel("Tab3", DTOutput('DT3'))
)
)
)
)
server <- function(input, output, session) {
output$DT1 = renderDT(iris)
DTProxy1 <- dataTableProxy("DT1")
output$DT2 = renderDT(iris)
DTProxy2 <- dataTableProxy("DT2")
output$DT3 = renderDT(iris)
DTProxy3 <- dataTableProxy("DT3")
observeEvent(c(input$search, input$tabsetPanelID), {
updateSearch(DTProxy1, keywords = list(global = input$search, columns = NULL))
updateSearch(DTProxy2, keywords = list(global = input$search, columns = NULL))
updateSearch(DTProxy3, keywords = list(global = input$search, columns = NULL))
})
}
shinyApp(ui, server)
What I currently have looks like the following:
You could add another tabsetPanel into each tabPanel of the main tabsetPanel.
mainPanel(tabsetPanel(
id = "tabsetPanelID",
type = "tabs",
tabPanel("Tab1", tabsetPanel(
tabPanel("SubPanelA1"), tabPanel("SubPanelA2")
)),
tabPanel("Tab2", tabsetPanel(
tabPanel("SubPanelB1"), tabPanel("SubPanelB2")
)),
tabPanel("Tab3", tabsetPanel(
tabPanel("SubPanelC1"), tabPanel("SubPanelC2")
))
))
I am creating a shiny app with some tabs and I am using the shinycssloaders package in order to show a spinner AFTER pressing the actionButton. I saw this post because I was having the same problem... I followed the solution that it was given to the post, but as I my app is different (it has tabPanels, it doesn't work properly, the spinner still apears).
For example, if you click on "Show the plot" in the first tab (selection) and then you want to want to do the log2 transformation o calculate the square root (3rd tab, calculations), before clicking the actionButton the spinner appears and the plot updates. It happens the same when you want to change the titles (2nd tab).
Does anyone know how to fix it?
Thanks very much in advance
The code:
library(shiny)
library(magrittr)
library(DT)
library(ggplot2)
library(shinycssloaders)
new_choices <- setNames(names(mtcars), names(mtcars))
ui <- fluidPage(
# Application title
titlePanel("My shiny app"),
sidebarLayout(
sidebarPanel(
tabsetPanel(
tabPanel("Selection",
selectInput("x_axis", "Choose x axis",
choices = new_choices),
selectInput("y_axis", "Choose y axis",
choices = new_choices),
hr(),
),
tabPanel("Titles",
hr(),
textInput(inputId = "title", "You can write the title:", value = "This is the title"),
textInput(inputId = "xlab", "You can re-name the x-axis:", value = "x-axis...."),
textInput(inputId = "ylab", "You can re-name the y-axis:", value = "y-axis ...."),
),
tabPanel("Calculations",
hr(),
checkboxInput("log2", "Do the log2 transformation", value = F),
checkboxInput("sqrt", "Calculate the square root", value = F),
)
),
actionButton(inputId = "drawplot", label = "Show the plot")
),
# Show a plot of the generated distribution
mainPanel(
# plotOutput("plot")
uiOutput("spinner"),
)
)
)
server <- function(input, output, session) {
data <- reactive({
mtcars
})
filtered_data <- reactive({
data <- data()
if(input$log2 == TRUE){
data <- log2(data+1)
}
if(input$sqrt == TRUE){
data <- sqrt(data)
}
return(data)
})
observeEvent(input$drawplot, {
output$spinner <- renderUI({
withSpinner(plotOutput("plot"), color="black")
})
output$plot <- renderPlot({
Sys.sleep(3)
ggplot() +
geom_point(data = filtered_data(),
aes_string(x = input$x_axis, y = input$y_axis)) +
xlab(input$xlab) +
ylab(input$ylab) +
ggtitle(input$title)
})
})
}
shinyApp(ui, server)
Is it OK like this? I'm not sure to understand all your requirements. To avoid the spinner at the start-up, I use a conditionalPanel. In the server code, I did some changes. It is not recommended to define some output inside an observer.
library(shiny)
library(magrittr)
library(ggplot2)
library(shinycssloaders)
new_choices <- setNames(names(mtcars), names(mtcars))
ui <- fluidPage(
# Application title
titlePanel("My shiny app"),
sidebarLayout(
sidebarPanel(
tabsetPanel(
tabPanel(
"Selection",
selectInput("x_axis", "Choose x axis",
choices = new_choices),
selectInput("y_axis", "Choose y axis",
choices = new_choices),
hr(),
),
tabPanel(
"Titles",
hr(),
textInput(inputId = "title", "You can write the title:", value = "This is the title"),
textInput(inputId = "xlab", "You can re-name the x-axis:", value = "x-axis...."),
textInput(inputId = "ylab", "You can re-name the y-axis:", value = "y-axis ...."),
),
tabPanel(
"Calculations",
hr(),
checkboxInput("log2", "Do the log2 transformation", value = F),
checkboxInput("sqrt", "Calculate the square root", value = F),
)
),
actionButton(inputId = "drawplot", label = "Show the plot")
),
# Show a plot of the generated distribution
mainPanel(
conditionalPanel(
condition = "input.drawplot > 0",
style = "display: none;",
withSpinner(plotOutput("plot"))
)
)
)
)
server <- function(input, output, session) {
data <- reactive({
mtcars
})
filtered_data <- reactive({
data <- data()
if(input$log2 == TRUE){
data <- log2(data+1)
}
if(input$sqrt == TRUE){
data <- sqrt(data)
}
return(data)
})
gg <- reactive({
ggplot() +
geom_point(data = filtered_data(),
aes_string(x = input$x_axis, y = input$y_axis)) +
xlab(input$xlab) +
ylab(input$ylab) +
ggtitle(input$title)
}) %>%
bindEvent(input$drawplot)
output$plot <- renderPlot({
Sys.sleep(3)
gg()
})
}
shinyApp(ui, server)
You need to isolate the expressions that you don't want to trigger the rendering event inside renderPlot
library(shiny)
library(magrittr)
library(DT)
library(ggplot2)
library(shinycssloaders)
new_choices <- setNames(names(mtcars), names(mtcars))
ui <- fluidPage(
# Application title
titlePanel("My shiny app"),
sidebarLayout(
sidebarPanel(
tabsetPanel(
tabPanel("Selection",
selectInput("x_axis", "Choose x axis",
choices = new_choices),
selectInput("y_axis", "Choose y axis",
choices = new_choices),
hr(),
),
tabPanel("Titles",
hr(),
textInput(inputId = "title", "You can write the title:", value = "This is the title"),
textInput(inputId = "xlab", "You can re-name the x-axis:", value = "x-axis...."),
textInput(inputId = "ylab", "You can re-name the y-axis:", value = "y-axis ...."),
),
tabPanel("Calculations",
hr(),
checkboxInput("log2", "Do the log2 transformation", value = F),
checkboxInput("sqrt", "Calculate the square root", value = F),
)
),
actionButton(inputId = "drawplot", label = "Show the plot")
),
# Show a plot of the generated distribution
mainPanel(
# plotOutput("plot")
uiOutput("spinner"),
)
)
)
server <- function(input, output, session) {
data <- reactive({
mtcars
})
filtered_data <- reactive({
data <- data()
if(input$log2 == TRUE){
data <- log2(data+1)
}
if(input$sqrt == TRUE){
data <- sqrt(data)
}
return(data)
})
observeEvent(input$drawplot, {
output$spinner <- renderUI({
withSpinner(plotOutput("plot"), color="black")
})
output$plot <- renderPlot({
Sys.sleep(3)
ggplot() +
geom_point(data = isolate(filtered_data()),
aes_string(x = isolate(input$x_axis), y = isolate(input$y_axis))) +
xlab(isolate(input$xlab)) +
ylab(isolate(input$ylab)) +
ggtitle(isolate(input$title))
})
})
}
shinyApp(ui, server)
Read more about shiny reactivity and isolation: https://shiny.rstudio.com/articles/isolation.html
I would like to align inputs/ outputs horizontally within columns. I can do this by splitting IDs, but I would prefer a way that dynamically splits the single input/ output ID into spaced columns.
Here is my code:
library(shinythemes)
library(shiny)
rm(list = ls())
ui <- navbarPage('Example',id = "inTabset",
tabPanel(title = "Example_1", value = "Example_1",
fluidPage(
tags$b( h4("Example_1", align = "left")),
theme = shinytheme("paper"),
fluidRow(
column(6,checkboxGroupInput("checkGroup", label ="",
choices = c(1,2,3,4,5,6,7,8),
selected = c(1,4,7)) )
),
br()
),
hr(),
verbatimTextOutput("example1")
),
tabPanel(title = "Example_2", value = "Example_2",
fluidPage(
tags$b( h4("Example_2", align = "left")),
br(),
fluidRow(
column(4, uiOutput("VarsInput")),
fluidRow(verbatimTextOutput("dataInfo")),
br(),
hr())
)
))
server <- function(input, output, session) {
output$example1 = renderPrint(input$checkGroup)
### output$example2 = ????
### i.e what data (a,b,c,d,e or f) has been chosen from the selectInput below?
K <- reactive({
length(input$checkGroup)
})
output$VarsInput <- renderUI({
NoV = K()
C = sapply(1:(ceiling(NoV)), function(i){paste0(input$checkGroup[i])})
output = tagList()
for(i in seq_along(1:ceiling(NoV))){
output[[i]] = tagList()
output[[i]][[1]] = selectInput(C[i], C[i], c("",c("a","b","c","d","e","f")))
}
output
})
}
shinyApp(ui, server)
As an example, the first input looks like this:
single column
I could, of course, split this into 2 (with the following code) to look like the following picture. However, this entails creating a separate ID, which I want to avoid.
2 columns
library(shinythemes)
library(shiny)
rm(list = ls())
ui <- navbarPage('Example',id = "inTabset",
tabPanel(title = "Example_1", value = "Example_1",
fluidPage(
tags$b( h4("Example_1", align = "left")),
theme = shinytheme("paper"),
fluidRow(
column(6,checkboxGroupInput("checkGroup1", label ="",
choices = c(1,2,3,4),
selected = c(1,4)) ),
column(6,checkboxGroupInput("checkGroup2", label ="",
choices = c(5,6,7,8),
selected = c(7)) )
),
br()
),
hr(),
verbatimTextOutput("example1")
))
server <- function(input, output, session) {
output$example1 = renderPrint(input$checkGroup1)
output$example2 = renderPrint(input$checkGroup2)
}
shinyApp(ui, server)
Many thanks.
Using inline=TRUE with width="100px" will control how wide you want to display. Then use
tags$head(
tags$style(
".checkbox-inline{margin-left:10px;"
)
)
to indent the first row. Try this
library(shinythemes)
library(shiny)
rm(list = ls())
ui <- navbarPage('Example',id = "inTabset",
tabPanel(title = "Example_1", value = "Example_1",
fluidPage(
tags$b( h4("Example_1", align = "left")),
theme = shinytheme("paper"),
fluidRow(
column(6,checkboxGroupInput("checkGroup", label ="", width="100px", inline=TRUE,
choices = c(1,2,3,4,5,6,7,8),
selected = c(1,4,7)) )
),
br()
),
hr(),
verbatimTextOutput("example1")
),
tags$head(
tags$style(
".checkbox-inline{margin-left:10px;"
)
),
tabPanel(title = "Example_2", value = "Example_2",
fluidPage(
tags$b( h4("Example_2", align = "left")),
br(),
fluidRow(
column(4, uiOutput("VarsInput")),
fluidRow(verbatimTextOutput("dataInfo")),
br(),
hr())
)
))
server <- function(input, output, session) {
output$example1 = renderPrint(input$checkGroup)
### output$example2 = ????
### i.e what data (a,b,c,d,e or f) has been chosen from the selectInput below?
K <- reactive({
length(input$checkGroup)
})
output$VarsInput <- renderUI({
NoV = K()
C = sapply(1:(ceiling(NoV)), function(i){paste0(input$checkGroup[i])})
output = tagList()
for(i in seq_along(1:ceiling(NoV))){
output[[i]] = tagList()
output[[i]][[1]] = selectInput(C[i], C[i], c("",c("a","b","c","d","e","f")))
}
output
})
}
shinyApp(ui, server)
I am trying to create a shiny app with multiple tabs. Each tab is to have its own sidebar. I haven't been able to get this to work. Any help on what is wrong would be appreciated.
Below is the code
ui <- fluidPage(
titlePanel("Hi"),
sidebarLayout(position = "left",
sidebarPanel(
conditionalPanel(condition = "input.tabs1==1",
selectizeInput('invar',"Reg in", choices = varnames, multiple = TRUE)),
conditionalPanel(condition = "input.tabs1==2",
selectizeInput('outvar',"Reg out", choices = predictors, multiple = FALSE)),
),
mainPanel(
tabsetPanel(id="tabs1",
tabPanel("input",value=1,plotOutput("Input"),
tabPanel("output",value=2,plotOutput("Output")
))))
))
First of all, check your code again. You made following mistakes:
one tabPanel is nested inside the other one
there's an extra comma at the end of the second conditionalPanel(), so you pass an empty element to sidebarPanel()
If I correct your mistakes and create a mock example, it works perfectly fine as is. So there isn't really a problem here:
ui <- fluidPage(
titlePanel("Hi"),
sidebarLayout(position = "left",
sidebarPanel(
conditionalPanel(condition = "input.tabs1==1",
selectizeInput('invar',"Reg in", choices = letters[1:3], multiple = TRUE)),
conditionalPanel(condition = "input.tabs1==2",
selectizeInput('outvar',"Reg out", choices = letters[4:6], multiple = FALSE))
),
mainPanel(
tabsetPanel(id="tabs1",
tabPanel("input",value=1,plotOutput("Input")),
tabPanel("output",value=2,plotOutput("Output"))
)
)
))
server <- function(input, output, session){
output$Input <- renderPlot(plot(1))
output$Output <- renderPlot(plot(2))
}
shinyApp(ui, server)
You could do this as well by using renderUI:
ui <- fluidPage(
titlePanel("Hi"),
sidebarLayout(position = "left",
sidebarPanel(
uiOutput("mysidebar")
),
mainPanel(
tabsetPanel(id="tabs1",
tabPanel("input",value=1,plotOutput("Input")),
tabPanel("output",value=2,plotOutput("Output")
)))
))
server <- function(input, output, session){
output$mysidebar <- renderUI({
if(input$tabs1 == 1){
selectizeInput('invar',"Reg in", choices = letters[1:3])
} else if(input$tabs1 == 2){
selectizeInput('outvar',"Reg out", choices = letters[4:6])
}
})
}
shinyApp(ui,server)
I do this in a very different but effective way.
shinyApp(
shinyUI(
fluidPage(
uiOutput('mainpage')
)
),
shinyServer(function(input, output, session) {
panel <- reactiveValues(side = NULL)
output$mainpage <- renderUI({
sidebarLayout(position = "left",
sidebarPanel(
uiOutput(panel$side)
),
mainPanel(
tabsetPanel(id="tabs1",
tabPanel("input",value=1,plotOutput("Input")),
tabPanel("output",value=2,plotOutput("Output"))
)
)
})
output$sideinput <- renderUI({
tagList(
selectizeInput('invar',"Reg in", choices = varnames, multiple = TRUE))
)
})
output$sideoutput <- renderUI({
tagList(
selectizeInput('outvar',"Reg out", choices = predictors, multiple =FALSE)
)
})
observeEvent(input$tabs1,{
panel$side <- switch(input$tabs1,
1 = 'sideinput',
2 = 'sideoutput')
})
basically I am using observers as my conditionals and assigning the value of the desired panel to the variable name assigned to that panel position
I have been working with the Shiny package, there is one function, which the user is able to select from a list of choices, based on the choice, the plot will update. however, right now the app does not update when the selection changes.
server.R
----------
library(shiny)
library(quantmod)
library(TTR)
shinyServer(function(input, output, session) {
selectedsymbol <- reactive({
symbol <- input$selectstock
})
output$stockplotoverview <- renderPlot({
symbolinput <- selectedsymbol()
getSymbols(symbolinput)
chartSeries(get(symbolinput))
addMACD()
addBBands()
})
output$candlechart <- renderPlot({
symbolinput <- input$selectstock
getSymbols(symbolinput)
candleChart(get(symbolinput),multi.col=TRUE,theme="white")
})
output$barchart <- renderPlot({
symbolinput <- input$selectstock
getSymbols(symbolinput)
barChart(get(symbolinput))
})
})
ui.R
library(shiny)
shinyUI(fluidPage(
# Application title
titlePanel("Hello Shiny!"),
# Sidebar component
sidebarLayout(
sidebarPanel(
selectInput("selectstockset", label = h3("Select the stock set"), choices = list("My Stock set" = 1,
"Good Stock Set" = 2,
"Customize" = 3), selected = 1),
selectInput("selectalgo", label = h3("Select the algorithm"), choices = list("Worst Increment" = 1,
"PAMR" = 2,
"SMA" = 3), selected = 1),
dateRangeInput("daterange", label = h3("Date Range")),
submitButton("Simulate")
),
# Show a plot of the generated distribution
mainPanel(
tabsetPanel(
tabPanel("Stock Set",
helpText("Select a stock to examine.
Information will be collected from yahoo finance."),
textInput("stocksetname", label = h4("Stock Set Name"),
value = "Enter text...") ,
# uiOutput("selectstock"),
selectInput("selectstock", label = h4("Select the stock"), choices = list("AAPL" = "AAPL",
"SBUX" = "SBUX",
"GS" = "GS")),
tabsetPanel(
tabPanel("Overview",
plotOutput("stockplotoverview")
),
tabPanel("Candle Chart",
plotOutput("candlechart")
),
tabPanel("Bar Chart",
plotOutput("barchart"))
),
hr(),
fluidRow(
column(3,
actionButton("addtostockset","Add to stock set"),
tags$style(type='text/css', "#addtostockset { align: right;}")
),
column(3,
actionButton("confirm","Confirm stock set"),
tags$style(type='text/css', "#confirm { align: right; }")
)
)),
tabPanel("Simulation Window"),
tabPanel("Statistical Result")
)
)
)))
Nothing is returned by your reactive conductor:
selectedsymbol <- reactive({
symbol <- input$selectstock
})
Use
selectedsymbol <- reactive({
symbol <- input$selectstock
return(symbol)
})