In my shinyApp i have a Data Frame which i want it to be reactive dependent on the Tab that is selected.
I tried the following, but it does not work. Any other ideas?
library(shiny)
library(shinydashboard)
library(tidyverse)
data = tibble(colOne=c(1:10), colTwo=c(rep(1, 5), rep(2, 5)))
header = dashboardHeader(disable = TRUE)
sidebar = dashboardSidebar(
sidebarMenu(
menuItem(text = "Name for first Tab", tabName = "start"),
menuItem(text = "Name for second Tab", tabName = "1"),
menuItem(text = "Name for third Tab", tabName = "2")
)
)
body = dashboardBody(
tabItems(
tabItem(tabName = "start"),
tabItem(tabName = "1"),
tabItem(tabName = "2")))
ui = dashboardPage(header = header, sidebar = sidebar, body = body)
server = function(input, output, session){
reactive_data = reactive({
data %>% filter(colTwo == input$tabName)
}
shinyApp(ui, server)
You can add an id to your sidebarMenu. Then, this can be used for resulting changes in menu selected. This should be a working example:
library(shiny)
library(shinydashboard)
library(tidyverse)
data = tibble(colOne=c(1:10), colTwo=c(rep(1, 5), rep(2, 5)))
header = dashboardHeader(disable = TRUE)
sidebar = dashboardSidebar(
sidebarMenu(id = "tab",
menuItem(text = "Name for first Tab", tabName = "start"),
menuItem(text = "Name for second Tab", tabName = "1"),
menuItem(text = "Name for third Tab", tabName = "2")
)
)
body = dashboardBody(
tabItems(
tabItem(tabName = "start"),
tabItem(tabName = "1"),
tabItem(tabName = "2")))
ui = dashboardPage(header = header, sidebar = sidebar, body = body)
server = function(input, output, session){
observe({
print(reactive_data())
})
reactive_data <- reactive({
data %>%
filter(colTwo == input$tab)
})
}
shinyApp(ui, server)
Related
I would like to set the starting page empty in my R shiny app. I mean the starting page shouldn't show anything except for the search bar. Then, once any value is plugged in the search bar, the result should show up. How can I achieve this?
My code is here:
library(shiny)
library(shinydashboard)
library(shinyWidgets)
BB = read.table("first.csv", header = TRUE,sep = ";",stringsAsFactors = FALSE)
shinyApp(
ui = dashboardPage(
dashboardHeader(title = "ciliogenics"),
dashboardSidebar(sidebar <- dashboardSidebar(
sidebarMenu(id = "SEARCH",
menuItem("SEARCH", tabName = "SEARCH"),
menuItem("Clinical Signs and Symptoms", tabName = "Clinical Signs and Symptoms"),
menuItem("Diseases", tabName = "Diseases"),
menuItem("Genes", tabName = "Genes"),
menuItem("Classifications and schemas", tabName = "Classification and schemas"),
menuItem("HELP", tabName = "HELP"),
menuItem("Related papers", tabName = "Related papers"),
menuItem("FAQs", tabName = "FAQs")
)
)),
dashboardBody(tabItems(tabItem(tabName = "SEARCH" ,
fluidRow(column(width=6,box(DT::dataTableOutput('myTable'), width=NULL)),
column(width=6,box(textOutput("myText"), width=NULL))))))
),
server = function(input, output, session){
mytbl <- BB
output$myTable <- DT::renderDataTable({DT::datatable(mytbl,
rownames=FALSE)})
output$myText <- renderText({ "The value entered in the seach box should appear here!" })
}
)
You can write your own search function. Using mtcars dataset -
library(shiny)
library(shinydashboard)
library(shinyWidgets)
library(DT)
shinyApp(
ui = dashboardPage(
dashboardHeader(title = "ciliogenics"),
dashboardSidebar(sidebar <- dashboardSidebar(
sidebarMenu(id = "SEARCH",
menuItem("SEARCH", tabName = "SEARCH"),
menuItem("Clinical Signs and Symptoms", tabName = "Clinical Signs and Symptoms"),
menuItem("Diseases", tabName = "Diseases"),
menuItem("Genes", tabName = "Genes"),
menuItem("Classifications and schemas", tabName = "Classification and schemas"),
menuItem("HELP", tabName = "HELP"),
menuItem("Related papers", tabName = "Related papers"),
menuItem("FAQs", tabName = "FAQs")
)
)),
dashboardBody(tabItems(tabItem(tabName = "SEARCH" ,
fluidRow(column(width=6,box(DT::dataTableOutput('myTable'), width=NULL)),
column(width=6,box(textOutput("myText"), width=NULL))))))
),
server = function(input, output, session){
rv <- reactiveValues(inds = 0, mytbl = mtcars)
output$myTable <- DT::renderDataTable({DT::datatable(rv$mytbl[rv$inds, ],rownames=FALSE, callback = JS(
"table.on( 'search.dt', function () {",
"Shiny.setInputValue( 'search', table.search() );",
"} );"
))})
output$myText <- renderText({paste0("Searching for ...", input$search)})
observeEvent(input$search, {
rv$inds <- which(rowSums(sapply(rv$mytbl, function(x) grepl(input$search, x))) > 0)
})
}
)
I found that menuSubItem content is not rendering in case of several (more than one) tabItems.
Minimal example demonstrating this behavior is below.
The desired behavior is to show content of the tabItem marked as selected = TRUE on startup. Now, the content shows up only after switching between menuSubItems in the sidebar.
How can I make it work?
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(title = "MINIMAL EXAMPLE"),
dashboardSidebar(
sidebarMenuOutput("menu")
),
dashboardBody(
uiOutput("body")
)
)
server <- function(input, output, session) {
output$menu <- renderMenu(
sidebarMenu(
menuItem(text = "TABS", tabName = "TABS", startExpanded = T,
menuSubItem(text = "tab1", tabName="tab1",
icon = icon("cube"), selected = TRUE),
menuSubItem(text = "tab2", tabName="tab2",
icon = icon("cube"), selected = FALSE)
)
)
)
output$body <- renderUI({
tabItems(
tabItem(tabName = "tab1",
h4("MY TEXT 1")
),
tabItem(tabName = "tab2",
h4("MY TEXT 2")
))
})
}
shinyApp(ui = ui, server = server)
Indeed, putting ui elements directly in UI solves it.
But the approach of putting everything inside ui is limited to situations that do not involve using reactive values. As I understand passing reactive value from server to ui is not possible in general (or limited to special cases). Please correct if I am wrong... Thanks
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(title = "MINIMAL EXAMPLE"),
dashboardSidebar(
sidebarMenuOutput("menu")
),
dashboardBody(
tabItems(
tabItem(tabName = "tab1",
h4("MY TEXT 1")
),
tabItem(tabName = "tab2",
h4("MY TEXT 2")
))
)
)
server <- function(input, output, session) {
output$menu <- renderMenu(
sidebarMenu(
menuItem(text = "TABS", tabName = "TABS", startExpanded = T,
menuSubItem(text = "tab1", tabName="tab1",
icon = icon("cube"), selected = TRUE),
menuSubItem(text = "tab2", tabName="tab2",
icon = icon("cube"), selected = FALSE)
)
)
)
}
shinyApp(ui = ui, server = server)
Renaming your output to something other than "body" helps - please see this.
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(title = "MINIMAL EXAMPLE"),
dashboardSidebar(
sidebarMenuOutput("menu")
),
dashboardBody(
uiOutput("myBodyOutput")
)
)
server <- function(input, output, session) {
output$myBodyOutput <- renderUI({
tabItems(
tabItem(tabName = "tab1",
h4("MY TEXT 1")
),
tabItem(tabName = "tab2",
h4("MY TEXT 2")
))
})
output$menu <- renderMenu(
sidebarMenu(id = "sidebarID",
menuItem(text = "TABS", tabName = "TABS", startExpanded = T,
menuSubItem(text = "tab1", tabName="tab1",
icon = icon("cube"), selected = TRUE),
menuSubItem(text = "tab2", tabName="tab2",
icon = icon("cube"), selected = FALSE)
)
)
)
}
shinyApp(ui = ui, server = server)
Hello I have a simple shiny app which includes a line graph. Firstly the user selects BOTH CHOICES of the checkboxgroup then the dateRangeInput() loads the relative dates and then I want to be able to create a line graph which will have this date range in the x-axis. I am not sure which is the correct way to give the date range as input to my plot.
OriginId = c("INT", "DOM", "INT","DOM","INT","DOM")
RequestedDtTm = c("2017-01-16 16:43:33
", "2017-01-17 16:43:33
", "2017-01-18 16:43:33
","2017-01-19 16:43:33",
"2017-01-18 16:43:33
","2017-01-19 16:43:33" )
ClientZIP=c(20000,24455,56000,45000,80000,45000)
testdata = data.frame(OriginId,RequestedDtTm,ClientZIP)
## ui.R ##
library(shinydashboard)
library(plotly)
dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody()
)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(title = "Basic dashboard"),
## Sidebar content
dashboardSidebar(
sidebarMenu(
menuItem("Dashboard", tabName = "dashboard", icon = icon("dashboard")),
menuItem("Change View", tabName = "widgets", icon = icon("th"))
)
),
## Body content
dashboardBody(
tabItems(
# First tab content
tabItem(tabName = "dashboard",
fluidRow(
box(plotlyOutput("plot3",height = 250))
)
),
# Second tab content
tabItem(tabName = "widgets",
fluidRow(
box(title="Line Graph",width = 12,
column(4,
checkboxGroupInput("checkGroup4", label = h3("Checkbox group"),
choices = list("Show Domestic" = "DOM", "Show International" = "INT"),
selected = "DOM")
),
column(4,
uiOutput("dt3")
),
column(4,
uiOutput("n3")
)
))
)
)
)
)
server <- function(input, output) {
output$plot3 <- renderPlotly({
data<-subset(testdata[,c(2,3)],testdata$OriginId %in% input$checkGroup4)
p <- plot_ly(data, x = format(as.Date(input$dateRange3), "%Y-%m"), y = ~ClientZIP, type = 'scatter', mode = 'lines')
})
output$dt3<-renderUI({
dateRangeInput('dateRange3',
label = 'Date range',
start = min(subset(as.POSIXct(testdata$RequestedDtTm),testdata$OriginId %in% input$checkGroup4)), end = max(subset(as.POSIXct(testdata$RequestedDtTm),testdata$OriginId %in% input$checkGroup4))
)
})
}
Here is a working example. When using dateRangeInput() you need to extract both, min (input$dateRange3[1]) and max (input$dateRange3[2]) values. Hope it helps.
OriginId = c("INT", "DOM", "INT","DOM","INT","DOM")
RequestedDtTm = c("2017-01-16", "2017-01-17", "2017-01-18","2017-01-19", "2017-01-18","2017-01-19")
ClientZIP=c(20000,24455,56000,45000,80000,45000)
testdata = data.frame(OriginId,RequestedDtTm,ClientZIP)
dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody()
)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(title = "Basic dashboard"),
## Sidebar content
dashboardSidebar(
sidebarMenu(
menuItem("Dashboard", tabName = "dashboard", icon = icon("dashboard")),
menuItem("Change View", tabName = "widgets", icon = icon("th"))
)
),
## Body content
dashboardBody(
tabItems(
# First tab content
tabItem(tabName = "dashboard",
fluidRow(
box(plotlyOutput("plot3"))
)
),
# Second tab content
tabItem(tabName = "widgets",
fluidRow(
box(title="Line Graph",width = 12,
column(4,
checkboxGroupInput("checkGroup4", label = h3("Checkbox group"),
choices = list("Show Domestic" = "DOM", "Show International" = "INT"),
selected = "DOM")
),
column(4,
uiOutput("dt3")
),
column(4,
uiOutput("n3")
)
))
)
)
)
)
server <- function(input, output) {
output$plot3 <- renderPlotly({
data <- dplyr::tbl_df(subset(testdata[,c(2,3)],testdata$OriginId %in% input$checkGroup4))
date_start <- as.character(input$dateRange3[1])
date_end <- as.character(input$dateRange3[2])
data$RequestedDtTm <- as.Date(data$RequestedDtTm, format = "%Y-%m-%d")
# data <- data %>% filter(RequestedDtTm >= date_start & RequestedDtTm <= date_end)
data <- data[as.Date(data$RequestedDtTm) >= date_start & as.Date(data$RequestedDtTm) <= date_end, ]
p <- plot_ly(data, x = ~RequestedDtTm, y = ~ClientZIP, type = 'scatter', mode = 'lines')
})
output$dt3<-renderUI({
dateRangeInput('dateRange3',
label = 'Date range',
start = min(subset(as.POSIXct(testdata$RequestedDtTm),testdata$OriginId %in% input$checkGroup4)), end = max(subset(as.POSIXct(testdata$RequestedDtTm),testdata$OriginId %in% input$checkGroup4))
)
})
}
shinyApp(ui, server)
hi i im trying to have the 'choices' in my pickerInput be dependent on what the user types in the search bar above. im using a spotify r package and if you search a certain artist the api returns a table of artists of the similar name and you need to choose which artist you want. anyways i want that table to go into the pickerInput and i can't seem to get it work.
ui <- dashboardPage(skin = "green",
dashboardHeader(title = "Lyric Prediction"),
dashboardSidebar(
sidebarMenu(
menuItem("Overview", tabName = "Overview", icon = icon("search")),
menuItem("Analysis", tabName = "Analysis", icon = icon("bar-chart-o"))
)
),
dashboardBody(
tags$head(
tags$style(HTML(".fa { font-size: 18px; }"))
),
tabItems(
# First tab content
tabItem(tabName = "Overview",
fluidRow(
column(12,
searchInput(
inputId = "search", label = "Search Artist on Spotify",
placeholder = "Search",
btnSearch = icon("search"),
btnReset = icon("remove"),
width = "500px"
)
), align = "center"
),
#HERE - how can i have pickerInput take in the output
#of "res" from the server?
fluidRow(pickerInput(choices = "res")
)),
)
)
server <- function(input, output) {
#function to take search input
#output list of possible artists
output$res <- renderTable({
#Rspotify
possibleArtists <- searchArtist(input$search,token=my_oauth)
possibleArtists <- as_tibble(possibleArtists)
myCols <- c("display_name","id")
colNums <- match(myCols,names(possibleArtists))
possibleArtists <- possibleArtists %>%
select(colNums)
possibleArtists
})
}
shinyApp(ui, server)
Use update method in an observeEvent like this:
observeEvent(input$search, {
#Rspotify
possibleArtists <- searchArtist(input$search,token=my_oauth)
possibleArtists <- as_tibble(possibleArtists)
myCols <- c("display_name","id")
colNums <- match(myCols,names(possibleArtists))
possibleArtists <- possibleArtists %>%
select(colNums)
updatePickerInput(
session = session,
inputId = "picker",
choices = possibleArtists
)
}, ignoreInit = TRUE)
Full example:
library(shiny)
library(shinydashboard)
library(shinyWidgets)
ui <- dashboardPage(
skin = "green",
dashboardHeader(title = "Lyric Prediction"),
dashboardSidebar(
sidebarMenu(
menuItem("Overview", tabName = "Overview", icon = icon("search")),
menuItem("Analysis", tabName = "Analysis", icon = icon("bar-chart-o"))
)
),
dashboardBody(
tags$head(
tags$style(HTML(".fa { font-size: 18px; }"))
),
tabItems(
# First tab content
tabItem(
tabName = "Overview",
fluidRow(
column(12,
searchInput(
inputId = "search", label = "Search Artist on Spotify",
placeholder = "Search",
btnSearch = icon("search"),
btnReset = icon("remove"),
width = "500px"
)
), align = "center"
),
pickerInput(inputId = "picker", label = "Choose an artist:", choices = NULL)
)
)
)
)
server <- function(input, output, session) {
observeEvent(input$search, {
updatePickerInput(
session = session,
inputId = "picker",
choices = c("The Beatles",
"The Beatles Recovered Band",
"Yesterday - A Tribute To The Beatles",
"The Beatles Revival Band & Orchestra")
)
}, ignoreInit = TRUE)
}
shinyApp(ui, server)
I need to render various menu sub-items based on some reactive data values. For each sub-item, I also need to associate linked output. I tried to link with tabName, but not sure what went wrong.
Below is an example. The desired output will be one box for each menu item/sub-item.
## This code snippet doesn't do what I need ----
shinyApp(
ui = dashboardPage(
dashboardHeader(),
dashboardSidebar(
sidebarMenu(
menuItemOutput("dynamic_menu"),
menuItem("Menu2", tabName = "menu2")
)
),
dashboardBody(
tabItems(
uiOutput("menu1_content"),
tabItem(tabName = "menu2", box("I am menu2"))
)
),
title = "Example"
),
server = function(input, output) {
output$dynamic_menu <- renderMenu({
submenu_list <- lapply(letters[1:5], function(x) {
menuSubItem(x, tabName = paste0("menu1-", x))
})
menuItem(
text = "Menu1",
startExpanded = TRUE,
do.call(tagList, submenu_list)
)
})
output$menu1_content <- renderUI({
content_list <- lapply(letters[1:5], function(x) {
tabItem(
tabName = paste0("menu1-", x),
box(x)
)
})
do.call(tagList, content_list)
})
}
)
## This code snippet does what I need ----
shinyApp(
ui = dashboardPage(
dashboardHeader(),
dashboardSidebar(
sidebarMenu(
menuItem(
"Menu1", startExpanded = TRUE,
menuSubItem("a", tabName = "menu1-a"),
menuSubItem("b", tabName = "menu1-b"),
menuSubItem("c", tabName = "menu1-c"),
menuSubItem("d", tabName = "menu1-d"),
menuSubItem("e", tabName = "menu1-e")
),
menuItem("Menu2", tabName = "menu2")
)
),
dashboardBody(
tabItems(
tabItem(tabName = "menu1-a", box("a")),
tabItem(tabName = "menu1-b", box("b")),
tabItem(tabName = "menu1-c", box("c")),
tabItem(tabName = "menu1-d", box("d")),
tabItem(tabName = "menu1-e", box("e")),
tabItem(tabName = "menu2", box("I am menu2"))
),
title = "Example"
)
),
server = function(input, output) {}
)
Answering my own question, but feel free to jump in if you have something more elegant.
I think my initial understanding of shiny dashboard is wrong, causing the app structure to be invalid.
The trick here is to add id to the sidebarMenu, so that page focus could be tracked and parsed later. Then each of the render function will listen on the input and render associated content.
shinyApp(
ui = dashboardPage(
dashboardHeader(),
dashboardSidebar(
sidebarMenu(
id = "sidebar_menu",
menuItemOutput("dynamic_menu"),
menuItem("Menu2", tabName = "menu2")
)
),
dashboardBody(
uiOutput("menu1_content"),
uiOutput("menu2_content")
),
title = "Example"
),
server = function(input, output, session) {
output$dynamic_menu <- renderMenu({
menu_list <- lapply(letters[1:5], function(x) {
menuSubItem(x, tabName = paste0("menu1-", x))
})
menuItem(
text = "Menu1",
startExpanded = TRUE,
do.call(tagList, menu_list)
)
})
output$menu1_content <- renderUI({
sidebar_menu <- tstrsplit(input$sidebar_menu, "-")
if (sidebar_menu[[1]] == "menu1") box(sidebar_menu[[2]])
})
output$menu2_content <- renderUI({
sidebar_menu <- tstrsplit(input$sidebar_menu, "-")
if (sidebar_menu[[1]] == "menu2") box("I am menu2")
})
}
)