Related
I'm trying to get 2 Select all filters to work together in the example below; The logic works fine for 1 filter.
##CREATE DATA
Director <- c("dir1", "dir1","dir1", "dir2", "dir2", "dir3", "dir3", "dir3")
Manager <- c("mgr1", "mgr","mgr3", "mgr4", "mgr5", "mgr6", "mgr7", "mgr8")
df <- data.frame(Director, Manager)
df$Sales <- sample(100, size = nrow(df), replace = TRUE)
director_choices = c("All", c(as.character(unique(df$Director))))
manager_choices = c("All", c(as.character(unique(df$Manager))))
ui <- dashboardPage(
# Application title
dashboardHeader(title = "Sales"),
# Sidebar with a slider input
dashboardSidebar(
sidebarMenu(
menuItem("Maps",
tabName = "Maps",
icon = icon("dashboard")),
hr(),
selectInput("Director", "Director", choices = director_choices, multiple = T, selected = "All"),
selectInput("Manager", "Manager", choices = manager_choices, multiple = T)
The filter below gets me the correct filtering just at the director level, my goal is to have a select all filter at the manager level that reacts to the director filer.
server <- function(input, output, session) {
observe({
if("All" %in% input$Director)
selected_choices = Director[-1]
else
selected_choices = input$Director
updateSelectInput(session, "Director", selected = selected_choices)
})
# Run the application
shinyApp(ui = ui, server = server)
You don't need to update the first selectInput. Just the second one should suffice. Try this.
##CREATE DATA
Director <- c("dir1", "dir1","dir1", "dir2", "dir2", "dir3", "dir3", "dir3")
Manager <- c("mgr1", "mgr2","mgr3", "mgr4", "mgr5", "mgr6", "mgr7", "mgr8")
df <- data.frame(Director, Manager)
df$Sales <- sample(100, size = nrow(df), replace = TRUE)
director_choices = c("","All", c(as.character(unique(df$Director))))
manager_choices = c(as.character(unique(df$Manager)))
ui <- dashboardPage(
# Application title
dashboardHeader(title = "Sales"),
# Sidebar with a slider input
dashboardSidebar(
sidebarMenu(
menuItem("Maps",
tabName = "Maps",
icon = icon("dashboard")),
hr(),
selectInput("Director", "Director", choices = director_choices, multiple = T, selected = "All"),
selectInput("Manager", "Manager", choices = manager_choices, multiple = T)
)
),
dashboardBody()
)
server <- function(input, output, session) {
observe({
df1 <- df[df$Director %in% input$Director,]
if (is.null(input$Director)) {selected_choices = ""
}else if("All" %in% input$Director) {selected_choices = manager_choices
}else selected_choices = unique(df1$Manager)
updateSelectInput(session, "Manager", choices = selected_choices)
})
}
# Run the application
shinyApp(ui = ui, server = server)
There are 3 districts which are A, B, and C in my data. I would like to establish a new district from the subdistricts of the current districts. For example, I select 2 of 3 districts via selectInput. And then, I would like to use bucket_list for selecting the subdistricts. The bucket list should show the subdistricts of selected districts. I do not want to see subdistricts of 3rd districts on a bucket list. I want to see only what I selected via selectInput. I could not manage this. After that, I want to create some tables using the DT package based on what I selected in the bucket list. My codes are below. I would be happy if you could help.
Here’s code:
library(shiny)
library(semantic.dashboard)
library(ggplot2)
library(plotly)
library(DT)
library(sortable)
library(gsheet)
data <- gsheet2tbl('https://docs.google.com/spreadsheets/d/1TqFoIQzTYyWKP8N43jcAxAV71TTA7ldfeRcGtpqfarM/edit#gid=201611728')
ui <- dashboardPage(
dashboardHeader(color = "green",title = "NEW DISTRICT", inverted = TRUE, size = "very wide"),
dashboardSidebar(
size = "thin", color = "teal",
sidebarMenu(
menuItem(tabName = "dist", "NEW DISTRICT ESTABLISHMENT", icon = icon("tree")),
menuItem(tabName = "subdist", "NEW SUBDISTRICT ESTABLISHMENT", icon = icon("tree"))
)
),
dashboardBody(
tabItems(
selected = 1,
tabItem(
tabName = "dist",
fluidRow(
fluidPage( textInput("caption", "ENTER THE NAME OF THE NEW DISTRICT", "", width = 500, placeholder = "PLEASE ENTER NEW NAME HERE!"),
fluidRow(column(5, verbatimTextOutput("value1"))),
hr(),
fluidPage(
selectInput("select", label = h3("PLEASE SELECT THE DISTRICTS!"),
choices = (data$DISTRICT),
selected = 0,
multiple= TRUE),
hr(),
fluidRow(column(3, verbatimTextOutput("value")))
),
),
if(interactive()) {
bucket_list(
header = c("NEW DISTRICT ESTABLISHMENT"),
add_rank_list(
text = "PLEASE SELECT SUBDISTRICT HERE!",
labels = "x",
options = sortable_options(
multiDrag = TRUE),
),
add_rank_list(
text = "select the subdistricts of the new district"
),
add_rank_list(
text = "select the subdistrict of the current district"
),
add_rank_list(
text = "select the subdistrict of the current district 2"
)
)
}
),
)
)
),
theme = "cerulean"
)
server <- shinyServer(function(input, output, session) {
observe({ print(input$select)
#output$x <- data$SUBDISTRICT[data$DISTRICT == input$select]
#output$x <- data %>% filter(DISTRICT == input$select) %>% select(SUBDISTRICT)
#updateSelectInput(session,"SUBDISTRICT","Select a SUBDISTRICT Category",choices = unique(x))
})
output$value <- renderText({paste(input$select)
})
output$value1 <- renderText({ input$caption })
})
shinyApp(ui, server)
Also, when I remove # on these codes:
observe({ print(input$select)
#output$x <- data$SUBDISTRICT[data$DISTRICT == input$select]
#output$x <- data %>% filter(DISTRICT == input$select) %>% select(SUBDISTRICT)
#updateSelectInput(session,"SUBDISTRICT","Select a SUBDISTRICT Category",choices = unique(x))
The shiny close itself.
Perhaps this will meet your needs
library(shiny)
library(semantic.dashboard)
library(ggplot2)
library(plotly)
library(DT)
library(sortable)
library(gsheet)
data <- gsheet2tbl('https://docs.google.com/spreadsheets/d/1TqFoIQzTYyWKP8N43jcAxAV71TTA7ldfeRcGtpqfarM/edit#gid=201611728')
ui <- dashboardPage(
dashboardHeader(color = "green",title = "NEW DISTRICT", inverted = TRUE, size = "very wide"),
dashboardSidebar(
size = "thin", color = "teal",
sidebarMenu(
menuItem(tabName = "dist", "NEW DISTRICT ESTABLISHMENT", icon = icon("tree")),
menuItem(tabName = "subdist", "NEW SUBDISTRICT ESTABLISHMENT", icon = icon("tree"))
)
),
dashboardBody(
tabItems(
selected = 1,
tabItem(
tabName = "dist",
fluidRow(
fluidPage( textInput("caption", "ENTER THE NAME OF THE NEW DISTRICT", "", width = 500, placeholder = "PLEASE ENTER NEW NAME HERE!"),
fluidRow(column(5, verbatimTextOutput("value1"))),
hr(),
fluidPage(
selectInput("select", label = h3("PLEASE SELECT THE DISTRICTS!"),
choices = unique(data$DISTRICT),
selected = 0,
multiple= TRUE),
hr(),
fluidRow(column(3, verbatimTextOutput("value"))),
DTOutput("t1"),
selectInput("subdistrict", label = h3("PLEASE SELECT THE SUBDISTRICTS!"),
choices = unique(data$SUBDISTRICT),
selected = 0,
multiple= TRUE)
)
),
uiOutput("mybucket")
),
)
)
),
theme = "cerulean"
)
server <- shinyServer(function(input, output, session) {
dat <- reactive({
data[data$DISTRICT %in% req(input$select),]
})
output$mybucket <- renderUI({
req(dat())
bucket_list(
header = c("NEW DISTRICT ESTABLISHMENT"),
add_rank_list(
text = "PLEASE SELECT SUBDISTRICT HERE!",
labels = unique(dat()$SUBDISTRICT),
options = sortable_options(
multiDrag = TRUE),
),
add_rank_list(
text = "select the subdistricts of the new district"
),
add_rank_list(
text = "select the subdistrict of the current district"
),
add_rank_list(
text = "select the subdistrict of the current district 2"
)
)
})
output$t1 <- renderDT(dat())
observeEvent(input$select, {
updateSelectInput(session,"subdistrict","Select a SUBDISTRICT Category",choices = unique(dat()$SUBDISTRICT))
})
output$value <- renderText({paste(input$select)})
output$value1 <- renderText({ input$caption })
})
shinyApp(ui, server)
I designed a Shiny app with a DT that can detect if the input fields changes and automatically update the values. Below is a screen shot and my code. This app works as I expected. When running this app, values are updated accordingly in DT based on the input values.
# Load the packages
library(tidyverse)
library(shiny)
library(DT)
# Create an empty data frame
dat <- tibble(
Input = c("SliderInput", "RadioButtons", "TextInput"),
Value = NA_character_
)
ui <- fluidPage(
titlePanel("DT: Document the Input Values"),
sidebarLayout(
sidebarPanel = sidebarPanel(
# The input widgets
sliderInput(inputId = "Slider", label = "The SliderInput", min = 1, max = 10, value = 5),
br(),
radioButtons(inputId = "Radio", label = "The RadioButtons", choices = c("A", "B", "C")),
br(),
textInput(inputId = "Text", label = "The TextInput", value = "Enter text ...")
),
mainPanel = mainPanel(
# The datatable
DTOutput(outputId = "d1")
)
)
)
server <- function(input, output, session){
# Save the dat to a reactive object
dat_save <- reactiveValues(df = dat)
output$d1 <- renderDT(dat, options = list(pageLength = 5), editable = TRUE, rownames = TRUE)
# Save the condition of the data table d1
d1_proxy <- dataTableProxy("d1")
# Edit the data table
observeEvent(input$d1_cell_edit, {
dat_save$df <- editData(dat_save$df, input$d1_cell_edit, d1_proxy)
})
# Update the input numbers for each cell
observeEvent(input$Slider, {
dat_save$df[1, "Value"] <- as.character(input$Slider)
})
observeEvent(input$Radio, {
dat_save$df[2, "Value"] <- input$Radio
})
observeEvent(input$Text, {
dat_save$df[3, "Value"] <- input$Text
})
observe({
replaceData(d1_proxy, dat_save$df, resetPaging = FALSE)
})
}
shinyApp(ui, server)
However, when I transferred the same code to a shinydahsboard with more than one tab. The DT cannot update the values when first initialize the app. Below is a screenshot and the code.
# Load the packages
library(tidyverse)
library(shiny)
library(shinydashboard)
library(DT)
# Create an empty data frame
dat <- tibble(
Input = c("SliderInput", "RadioButtons", "TextInput"),
Value = NA_character_
)
ui <- function(request) {
dashboardPage(
# The header panel
header = dashboardHeader(title = ""),
# The sidebar panel
sidebar = dashboardSidebar(
# The sidebar manual
sidebarMenu(
id = "tabs",
# Tab 1
menuItem(
text = "Tab1",
tabName = "Tab1"
),
# Tab 2
menuItem(
text = "DT Example",
tabName = "DT_E"
)
)),
# The main panel
body = dashboardBody(
tabItems(
tabItem(
# The tab name
tabName = "Tab1",
h2("Placeholder")
),
# Tab 2: DT example
tabItem(
# The tab name
tabName = "DT_E",
h2("DT: Document the Input Values"),
sidebarPanel(
# The input widgets
sliderInput(inputId = "Slider", label = "The SliderInput", min = 1, max = 10, value = 5),
br(),
radioButtons(inputId = "Radio", label = "The RadioButtons", choices = c("A", "B", "C")),
br(),
textInput(inputId = "Text", label = "The TextInput", value = "Enter text ...")
),
# The datatable
DTOutput(outputId = "d1")
)
)
)
)
}
server <- function(input, output, session){
# Save the dat to a reactive object
dat_save <- reactiveValues(df = dat)
output$d1 <- renderDT(dat, options = list(pageLength = 5), editable = TRUE, rownames = TRUE)
# Save the condition of the data table d1
d1_proxy <- dataTableProxy("d1")
# Edit the data table
observeEvent(input$d1_cell_edit, {
dat_save$df <- editData(dat_save$df, input$d1_cell_edit, d1_proxy)
})
# Update the input numbers for each cell
observeEvent(input$Slider, {
dat_save$df[1, "Value"] <- as.character(input$Slider)
})
observeEvent(input$Radio, {
dat_save$df[2, "Value"] <- input$Radio
})
observeEvent(input$Text, {
dat_save$df[3, "Value"] <- input$Text
})
observe({
replaceData(d1_proxy, dat_save$df, resetPaging = FALSE)
})
}
shinyApp(ui, server)
Notice that if there is only one tab in the shinydashboard, the DT will work. If changed any input values after initializing the app, the DT will also work. But it is a mystery to me why the DT cannot work in the first place when the shinydashboard has multiple tabs. Any suggestions or comments would be great.
After further search, I found a solution from this post and this post. For some reasons, the default setting for shinydashboard is to ignore hidden objects starting the second tab. In my case, adding outputOptions(output, "d1", suspendWhenHidden = FALSE) solves the issue. Below is the complete code.
# Load the packages
library(tidyverse)
library(shiny)
library(shinydashboard)
library(DT)
# Create an empty data frame
dat <- tibble(
Input = c("SliderInput", "RadioButtons", "TextInput"),
Value = NA_character_
)
ui <- function(request) {
dashboardPage(
# The header panel
header = dashboardHeader(title = ""),
# The sidebar panel
sidebar = dashboardSidebar(
# The sidebar manual
sidebarMenu(
id = "tabs",
# Tab 1
menuItem(
text = "Tab1",
tabName = "Tab1"
),
# Tab 2
menuItem(
text = "DT Example",
tabName = "DT_E"
)
)),
# The main panel
body = dashboardBody(
tabItems(
tabItem(
# The tab name
tabName = "Tab1",
h2("Placeholder")
),
# Tab 2: DT example
tabItem(
# The tab name
tabName = "DT_E",
h2("DT: Document the Input Values"),
sidebarPanel(
# The input widgets
sliderInput(inputId = "Slider", label = "The SliderInput", min = 1, max = 10, value = 5),
br(),
radioButtons(inputId = "Radio", label = "The RadioButtons", choices = c("A", "B", "C")),
br(),
textInput(inputId = "Text", label = "The TextInput", value = "Enter text ...")
),
# The datatable
DTOutput(outputId = "d1")
)
)
)
)
}
server <- function(input, output, session){
# Save the dat to a reactive object
dat_save <- reactiveValues(df = dat)
output$d1 <- renderDT(dat, options = list(pageLength = 5), editable = TRUE, rownames = TRUE)
outputOptions(output, "d1", suspendWhenHidden = FALSE)
# Save the condition of the data table d1
d1_proxy <- dataTableProxy("d1")
# Edit the data table in tab 3
observeEvent(input$d1_cell_edit, {
dat_save$df <- editData(dat_save$df, input$d1_cell_edit, d1_proxy)
})
# Update the input numbers for each cell
observeEvent(input$Slider, {
dat_save$df[1, "Value"] <- as.character(input$Slider)
})
observeEvent(input$Radio, {
dat_save$df[2, "Value"] <- input$Radio
})
observeEvent(input$Text, {
dat_save$df[3, "Value"] <- input$Text
})
observe({
replaceData(d1_proxy, dat_save$df, resetPaging = FALSE)
})
}
shinyApp(ui, server)
The process_map() function in the server in the R shiny script creates the diagram image as below. My requirement is that there are two attributes "FUN" and "units" that are part of the performance() function. They have standard four values each that are available in the ui code below under PickerInput ID's Case4 and Case5. Currently, I am hard coding the value to create the map, can you help me to use the id's in the server code and make it dynamic such that when I select the value in the PickerInput, the formula fetches the value directly. Thanks and please help.
library(shiny)
library(shinydashboard)
library(bupaR)
library(processmapR)
library(lubridate)
library(dplyr)
library(edeaR)
library(shinyWidgets)
library(DiagrammeR)
ui <- dashboardPage(
dashboardHeader(title = "Diagram Plot",titleWidth = 290),
dashboardSidebar(width = 0),
dashboardBody(
tabsetPanel(type = "tab",
tabPanel("Overview", value = 1,
box(
column(1,
dropdown(
pickerInput(inputId = "resources",
label = "",
choices = c("Throughput Time"),
choicesOpt = list(icon = c("fa fa-bars",
"fa fa-bars",
"fa fa-safari")),
options = list(`icon-base` = "")),
circle = FALSE, status = "primary", icon = icon("list", lib = "glyphicon"), width = "300px"
),
conditionalPanel(
condition = "input.resources == 'Throughput Time' ",
tags$br(),
tags$br(),
tags$br(),
dropdown(
pickerInput(inputId = "Case4",
label = "Select the Process Time Summary Unit",
choices = c("min","max","mean","median"), options = list(`actions-box` = TRUE),
multiple = F),
circle = FALSE, status = "primary", icon = icon("eye-close", lib = "glyphicon"), width = "300px"
),
tags$br(),
tags$br(),
tags$br(),
dropdown(
pickerInput(inputId = "Case5",
label = "Select the Process Time Unit",
choices = c("mins","hours","days","weeks"), options = list(`actions-box` = TRUE),
multiple = F, selected = "days"),
circle = FALSE, status = "primary", icon = icon("eye-close", lib = "glyphicon"), width = "300px"
))),
title = "Process Map",
status = "primary",height = "575", width = "500",
solidHeader = T,
column(10,grVizOutput("State")),
align = "left")
),
id= "tabselected"
)))
server <- function(input, output) {
output$State <- renderDiagrammeR(
{
if(input$resources == "Throughput Time")
patients %>% process_map(performance(FUN = mean,units = "days"))
else
return()
})}
shinyApp(ui, server)
test this:
output$State <- renderDiagrammeR({
if(input$resources == "Throughput Time")
{
if(input$Case4=="mean"){
patients %>% process_map(performance(FUN = mean,units = input$Case5))}
else if(input$case4=="min"){
patients %>% process_map(performance(FUN = min,units = input$Case5))
}else if(input$case4=="max"){
patients %>% process_map(performance(FUN = max ,units = input$Case5))
}else{
patients %>% process_map(performance(FUN = median ,units = input$Case5))
}
}else
return()
})
or you can use this:
patients %>%
process_map(performance(FUN = eval(parse(text=input$Case4)) ,units = input$Case5))
enjoy;)
here is a sample:
library(shiny)
ui <- fluidPage(
selectInput(inputId = "func", label = "Choose The Function", choices = c("mean", "sum", "median"))
,
textOutput("text")
)
server <- function(input, output, session) {
main_data <- reactive({
data.frame(a= rnorm(100), b=rnorm(100) )
})
output$text <- renderText({
df <- main_data()
apply(df,2, FUN = eval(parse(text=input$func)) )
})
}
shinyApp(ui = ui, server = server)
You could use do.call to call a function from its name, see the example below. You can add arguments by adding them in the list in the do.call function, e.g. list(x,units=input$Case5).
library(shiny)
x=c(1,2,3,4,5,6,7)
ui <- fluidPage(
selectInput('select','Select Function: ', choices=c('mean','max','min','median')),
textOutput('text')
)
server <- function(input,output)
{
output$text <- renderText({
result = do.call(input$select, list(x))
paste0('The ', input$select, ' of [', paste(x,collapse=', '),'] is ', result)
})
}
shinyApp(ui,server)
Hope this helps!
I am trying to build a shiny dashboard app, where I process the input data and produce summary statistics based on the user supplied grouping variables. The last step, where I am stuck is to
implement a working function , which enables the user to select to display only a subset of the columns after the calculation of the summary statistics.
My attempt is in the lines after output$select_col in global.R . Right now each time I try to use the selector shiny crashes with the error "incorrect number of dimensions".
global.R
# Shiny
library(shiny)
library(shinydashboard)
library(shinyjs)
# Data tools
library(dplyr)
library(tidyr)
library(tibble)
library(data.table)
server.R
server <- function(input, output) {
raw_tables<-reactive({
mtcars
})
output$cyl <- renderUI({
selectInput(inputId = "cyl",
label = "Which number of cyl to consider",
choices = c(4,6,8),
selected = NULL,
multiple=TRUE)
})
filtered_tables<-
reactive({
if(is.null(input$cyl)){
data_filtered <- raw_tables()
}
else{
data_filtered <- raw_tables() %>% filter(cyl %in% input$cyl)
}
})
new_statistics <- reactive({
if(is.null(filtered_tables())){
return(NULL)
}
if(length(input$grouping_variables) == 0){
op <- filtered_tables() %>%
ungroup()
} else {
op <- filtered_tables() %>%
group_by_(.dots = input$grouping_variables)
}
op %>% #
summarise(nr_cars = n(),
mean_mpg = mean(mpg,na.rm=T),
sd_mpg = sd(mpg,na.rm=T))
})
nice_table <-reactive({
if(is.null(new_statistics())){
return(NULL)
}
DT::datatable(new_statistics(),
colnames = c(
"nbr cars"="nr_cars" ,
"mean mpg"="mean_mpg",
"sd mpg"="sd_mpg"
), selection = list(target = 'column') , extensions = c('ColReorder'), options = list(colReorder = TRUE)
) %>%
DT::formatRound(columns=c(
"nbr cars" ,
"mean mpg",
"sd mpg"),
digits=2)
})
output$select_col <- renderUI({
if(is.null(nice_table())){
return(NULL)
}
selectInput("col", "Select columns:", choices = colnames(nice_table()), selected=NULL, multiple=TRUE)
})
output$statistics = DT::renderDataTable({
if(length(input$col)>0)
{
return(DT::datatable(nice_table()[, colnames(nice_table()) %in% input$col]))
}
else
{
return(NULL)
}
})
}
ui.R
dbHeader <- dashboardHeader(title = "test",
titleWidth = 250)
sidebar <- dashboardSidebar(
width = sidebarWidth,
br(),
sidebarMenu(
menuItem(text = "Data View",
tabName = "dat_view",
icon = icon("cloud-download")
)
)
)
body <- dashboardBody(
# Add shinyJS mini-sidebar
shinyjs::useShinyjs(),
tabItems(
tabItem(tabName = "dat_view",
fluidPage(
sidebarLayout(
sidebarPanel(width=2,
selectInput(inputId = 'grouping_variables',
label = 'Which grouping var?',
choices = c("cyl","gear","carb"),
selected = NULL,
multiple=TRUE,
selectize=TRUE),
uiOutput("cyl"),
uiOutput("select_col")
)
,
mainPanel(
tabsetPanel(id="dat_view_tabs",
tabPanel(
'statistics',
DT::dataTableOutput(outputId='statistics')
)
)
)
)))))
ui <- dashboardPage(skin = "blue",
header = dbHeader,
sidebar = sidebar,
body = body)