Reputation: 47
I am trying to create an application which dynamically creates different tabs in which there is a version of my initial table filtered according to a variable (among all those selected by the CheckboxGroupInput
).
For example if I try with the table iris in which there is a variable Species taking the 3 modalities virginita, setosa and versicolor, then I would like to obtain a first tab with the observations where Species = virginita
, a second where Species = setosa
etc ...
I found a solution on this forum for dynamically create the tabs but in all of them, the dataset obtained is the one filtered by the last input selected (here versicolor).
I suspect a problem with lapply
but I'm new on R
and shiny and I can't seem to find a solution.
A little help would be appreciated !
Thanks everyone!
library(shiny)
ui <- pageWithSidebar(
headerPanel = headerPanel('iris'),
sidebarPanel = sidebarPanel(checkboxGroupInput("filter","Choices",c("virginita","setosa","versicolor"), selected=c("virginita","setosa","versicolor"))
),
mainPanel(uiOutput("my_tabs"))
)
server <- function(input, output, session) {
df = iris
output$my_tabs = renderUI({
dt <- list()
for ( i in 1:3) {
output[[paste0("tab",as.character(i))]] <- DT::renderDataTable ({
dt2 <- subset(df, Species==input$filter[i])
return(dt2)
})
dt[[i]] <- DT::DTOutput(paste0("tab",as.character(i)))
}
criteria <- input$filter
n=length(criteria)
myTabs = lapply(1:n, function(j){
tabPanel(criteria[j],
renderUI(dt[[j]])
)
})
do.call(tabsetPanel, myTabs)
})
}
runApp(list(ui = ui, server = server))
Upvotes: 2
Views: 334
Reputation: 30474
There can be problems using for loops in shiny apps:
https://chasemc.github.io/post/the-subtleties-of-shiny-reactive-programming-lapply-and-for-loops/
Instead would use lapply
.
Also, I would separate your dynamic creation of output
for different tabs to an observe
expression (although you could put it at the top of output$my_tabs
).
In addition, I noticed that virginica
was misspelled in the ui
. Otherwise, this includes most of your same code and seems to work.
library(shiny)
library(DT)
ui <- pageWithSidebar(
headerPanel = headerPanel('iris'),
sidebarPanel = sidebarPanel(checkboxGroupInput("filter","Choices",c("virginica","setosa","versicolor"),
selected=c("virginica","setosa","versicolor"))
),
mainPanel(uiOutput("my_tabs"))
)
server <- function(input, output, session) {
df = iris
output$my_tabs = renderUI({
myTabs = lapply(1:length(input$filter), function(i) {
tabPanel(input$filter[i],
DT::DTOutput(paste0("tab",i))
)
})
do.call(tabsetPanel, myTabs)
})
observe(
lapply(1:length(input$filter), function(i) {
output[[paste0("tab",i)]] <- DT::renderDataTable({
subset(df, Species == input$filter[i])
})
})
)
}
runApp(list(ui = ui, server = server))
Upvotes: 1