Reputation: 255
I am trying to create a Shiny App and I am facing issues with respect to the Usage of renderUI. Kindly find the below code which I used creating the shiny app. Here is the UI Script and the sample data frame.
library(shiny)
library(tidyverse)
library(data.table)
library(ggplot2)
Source_Data <-
data.frame(
key = c(1, 1, 1, 2, 2, 2, 3, 3, 3),
Product_Name = c(
"Table",
"Table",
"Chair",
"Table",
"Bed",
"Bed",
"Sofa",
"Chair",
"Sofa"
),
Product_desc = c("XX", "XXXX", "YY", "X", "Z", "ZZZ", "A", "Y", "A"),
Cost = c(1, 2, 3, 4, 2, 3, 4, 5, 6)
)
ui <- fluidPage(titlePanel("Demo"),
sidebarLayout(
sidebarPanel(
sliderInput(
"key",
"keys",
min = 1,
max = 3,
value = c(1, 3),
step = 1
),
selectInput("Product", "List of Products", choices = NULL),
uiOutput("sublist")
),
mainPanel(tabsetPanel(
type = "tabs",
tabPanel("table_data", DT::dataTableOutput("table")),
tabPanel("Visualizing Data", plotOutput("plot"))
))
))
Here is the Server R script
server <- function(input, output, session) {
observe({
x <-
Source_Data %>% filter(key %in% input$key) %>% select (Product_Name)
updateSelectInput(session, "Product", "List of Products", choices =
unique(x))
})
#### Using render UI here #######
output$sublist <- renderUI({
tagList(
z <- Source_Data %>% filter(key %in% input$keys & Product_Name %in%
input$Product) %>% select (Product_desc),
checkboxGroupInput("sublist_1", "Descriptions", z)
)
})
output_func <- reactive({
key_input <- input$key
Product_input <- input$Product
cat_input <- input$sublist
d <- Source_Data %>% dplyr::select(key,
Product_Name,
Product_desc,
Cost) %>% dplyr::filter (key %inrange%
key_input,
Product_Name ==
Product_input,
Product_desc ==
cat_input)
return(d)
})
output$table1 <-
DT::renderDataTable({
output_func()
})
output$plot <-
renderPlot({
ggplot(output_func(), aes (key, cost, fill = Product_desc))
})
}
shinyApp(ui = ui, server = server)
Here the Variable key will be in the form of a Slider Input and Depending upon the Selected Key/Keys, I display the product names in a Dropdown list. Now with render UI What i am trying to do is depending upon the selected product name I want the product descriptions to be displayed in the form of a Checkbox. So that I can select the single/Multiple checkboxes and change the table and plot displays Dynamically.
In such a way that the Product Descriptions will change for each product name under Each each key value. Also if i have not selected any product name then no check boxes should be appearing.
But when i try to do this, I fail very badly and also I am getting error "Error in : Result must have length 9, not 0"
Any help on how to proceed further on this will help me a lot. Thanks in Advance.
Upvotes: 1
Views: 588
Reputation: 30474
Maybe this has been fixed by now, but just in case here is a working solution.
A few issues were identified:
input$key
not input$keys
, input$sublist_1
instead of input$sublist
, output$table
instead of output$table1
, Cost
(capital 'C') instead of cost
, etc.Source_Data
use pull
instead of select
to provide a vector of checkbox options to checkboxGroupInput
output_func
use req
for inputs as recommended to require key
, Product
, and sublist_1
before trying to subset Source_Data
output_func
you may want Product_desc %in% cat_input
to address multiple checkboxes checked at one time, so not comparing a string with a vector of stringsHere is the server code:
server <- function(input, output, session) {
observe({
x <- Source_Data %>%
filter(key %in% input$key) %>%
select (Product_Name)
updateSelectInput(session, "Product", "List of Products", choices = unique(x))
})
#### Using render UI here #######
output$sublist <- renderUI({
z <- Source_Data %>%
filter(key %in% input$key & Product_Name %in% input$Product) %>%
pull (Product_desc)
tagList(
checkboxGroupInput("sublist_1", "Descriptions", z)
)
})
output_func <- reactive({
req(input$key, input$Product, input$sublist_1)
key_input <- input$key
Product_input <- input$Product
cat_input <- input$sublist_1
d <- Source_Data %>%
dplyr::select(key,
Product_Name,
Product_desc,
Cost) %>%
dplyr::filter (key %inrange% key_input,
Product_Name == Product_input,
Product_desc %in% cat_input)
return(d)
})
output$table <-
DT::renderDataTable({
output_func()
})
output$plot <-
renderPlot({
output_func() %>%
ggplot(aes(Product_Name, Cost)) +
geom_col(aes(fill = Product_desc), position = position_dodge(preserve = "single"))
})
}
I hope this is helpful - let me know if this is what you had in mind. Good luck!
Upvotes: 3