I have this working app: It is a follow-up question of some previous questions:
library(shiny)
library(vtree)
df <- tibble(A = c(rep("nature", 18), rep("not nature", 9)),
B = rep(c("animal", "plant", "machine"), each=9),
C = c(rep(c("dog", "cat", 'mouse'), 3),
rep(c("tree", "flower", "grass"), 3),
rep(c("car", "plane", "train"), 3)
)
)
# Define UI ----
ui <- pageWithSidebar(
# App title ----
headerPanel("my app"),
# Sidebar panel for inputs ----
sidebarPanel(
selectizeInput("levels", label = "Levels", choices = NULL, multiple = TRUE),
selectizeInput("valuesA", label= "Values_A", choices = NULL, multiple=TRUE),
selectizeInput("valuesB", label= "Values_B", choices = NULL, multiple=TRUE),
selectizeInput("valuesC", label= "Values_C", choices = NULL, multiple=TRUE),
),
# Main panel for displaying outputs ----
mainPanel(
vtreeOutput("VTREE")
)
)
# Define server logic to plot ----
server <- function(input, output,session) {
df <- reactiveVal(df)
vector <- c("A","B", "C")
observe({
updateSelectizeInput(session, "levels", choices = colnames(df()[vector]), selected = NULL)
updateSelectizeInput(session, "valuesA", choices = unique(df()$A))
updateSelectizeInput(session, "valuesB", choices = unique(df()$B))
updateSelectizeInput(session, "valuesC", choices = unique(df()$C))
})
output[["VTREE"]] <- renderVtree({
vtree(df(), c(input$levels),
sameline = TRUE,
keep=list(A=input$valuesA,
B = input$valuesB,
C = input$valuesC),
pngknit=FALSE,
horiz=TRUE,height=450,width=850)
})
}
shinyApp(ui, server)
I want to control the selectizeInput
fields in that way that they dependent on each other:
Let me explain:
Scenario 1:
If Levels
== A
the user should be able to select from Values_A
, not Values_B and not Values_C
.
Scenario 2:
If Levels
==A
and Values_A
== nature
then in Values_B
only animal
and plant
should be visible to select and not machine
because machine
is not nature
.
Scenario 3:
If Levels
== A
and Values_A
== nature
and Values_B
== animal
then in Values_C
only dog
cat
mouse
should be visible:
Hi I think this does what you are looking for
library(shiny)
library(vtree)
library(dplyr)
df <- tibble(A = c(rep("nature", 18), rep("not nature", 9)),
B = rep(c("animal", "plant", "machine"), each=9),
C = c(rep(c("dog", "cat", 'mouse'), 3),
rep(c("tree", "flower", "grass"), 3),
rep(c("car", "plane", "train"), 3)
)
)
# Define UI ----
ui <- pageWithSidebar(
# App title ----
headerPanel("my app"),
# Sidebar panel for inputs ----
sidebarPanel(
selectizeInput("levels", label = "Levels", choices = NULL, multiple = TRUE),
selectizeInput("valuesA", label= "Values_A", choices = NULL, multiple=TRUE),
selectizeInput("valuesB", label= "Values_B", choices = NULL, multiple=TRUE),
selectizeInput("valuesC", label= "Values_C", choices = NULL, multiple=TRUE),
),
# Main panel for displaying outputs ----
mainPanel(
vtreeOutput("VTREE")
)
)
# Define server logic to plot ----
server <- function(input, output,session) {
df_A <- reactive({
filtered_df <- df
if(!is.null(input$valuesA)){
filtered_df <- filtered_df %>%
filter(A %in% input$valuesA)
}
filtered_df
})
df_B <- reactive({
if(!is.null(input$valuesB)){
filtered_df <- df_A() %>%
filter(B %in% input$valuesB)
} else {
df_A()
}
})
df_C <- reactive({
if(!is.null(input$valuesC)){
df_B() %>%
filter(C %in% input$valuesC)
} else {
df_B()
}
})
vector <- c("A","B", "C")
observe({
# browser()
updateSelectizeInput(session, "levels", choices = colnames(df[vector]), selected = input$levels)
updateSelectizeInput(session, "valuesA", choices = unique(df$A), selected = input$valuesA)
updateSelectizeInput(session, "valuesB", choices = unique(df_A()$B), selected = input$valuesB)
updateSelectizeInput(session, "valuesC", choices = unique(df_B()$C), selected = input$valuesC)
})
output[["VTREE"]] <- renderVtree({
vtree(df_C(), c(input$levels),
sameline = TRUE,
keep=list(A=input$valuesA,
B = input$valuesB,
C = input$valuesC),
pngknit=FALSE,
horiz=TRUE,height=450,width=850)
})
}
shinyApp(ui, server)
Hope this helps, Bertil