R Shiny - add tabPanel to tabsetPanel dynamically (with the use of renderUI)
Here you go. The code is fairly self explanatory.
library(shiny)
runApp(list(
ui = pageWithSidebar(
headerPanel('Dynamic Tabs'),
sidebarPanel(
numericInput("nTabs", 'No. of Tabs', 5)
),
mainPanel(
uiOutput('mytabs')
)
),
server = function(input, output, session){
output$mytabs = renderUI({
nTabs = input$nTabs
myTabs = lapply(paste('Tab', 1: nTabs), tabPanel)
do.call(tabsetPanel, myTabs)
})
}
))
Use renderUI to insert additional tabPanel in R Shiny
You can use insertTab
or appendTab
:
ui <- fluidPage(sidebarLayout(sidebarPanel(),
mainPanel(
tabsetPanel(id = "myTabsetPanel",
tabPanel("static_tab", tabName = "static_tab"))
)))
server <- function(input, output) {
appendTab(inputId = "myTabsetPanel",
tabPanel("render_tab", p('it worked')))
}
shinyApp(ui = ui, server = server)
renderUI
won't work as it creates a div
tag - however, you need to create a li
tag.
How to create dynamic tabSetPanels with the same selected tab that reacts to user input in R Shiny?
The value of a
tabPanel
must be a character string :output$set1 <- renderUI({
tabs <- list()
for(i in seq_len(input$tabSelector)){
tabs[[i]] <- tabPanel(
title = paste0("tab",i),
value = as.character(i),
numericInput(
paste0("num",i),
"Number",
value = 0
)
)
}
do.call(tabsetPanel, c(tabs,
list(id = "set1",
selected = as.character(input$tabSelector))
))
})In
output$set2
you don't need to set the value of theselected
argument, because it will be set by theupdateTabsetPanel
.Duplicated ids are not allowed in HTML, so you have to change the id
paste0("num",i)
of your numeric inputs to something else in one of the two tabsets.
Dynamically Generate Plots in Conditional Tabs using renderUI in Shiny
Your example isn't exactly minimal so i did some stripping away. First the data and helper functions
library(shiny)
library(ggplot2)
channels = c("Affiliate","Email","Media","SEO")
nObs = c(round(runif(1,100,200)))
myData = data.frame(
Campaign = unlist(lapply(channels, FUN = function(x) paste(x,seq(from=1,to=nObs,by=1),sep=""))),
Channel = rep(channels,nObs),
Return = runif(nObs*length(channels),50,500),
Spend = runif(nObs*length(channels),10,100)
)
plotSingle = function(myData, channelName){
ggplot(myData[which(myData$Channel==channelName),], aes(x = Spend, y = Return)) +
geom_point(color="black") +
theme(panel.background = element_rect(fill = 'grey85'),
panel.grid.major = element_line(colour = "white"))
}
Now the UI
ui <- fluidPage(
headerPanel('Plot Testing'),
mainPanel(
uiOutput('mytabs'),
plotOutput('scatterPlot')
)
)
Note that we only use one plotOutput here. What we will do is just change the plot it's showing based on the currently selected tab. Here's the server code
server = function(input, output) {
rawData <- reactive({
myData
})
output$mytabs = renderUI({
if(is.null(rawData())){return ()}
channels = unique(rawData()$Channel)
myTabs = unname(Map(tabPanel, channels))
do.call(tabsetPanel, c(myTabs, id="channeltab"))
})
output$scatterPlot <- renderPlot({
if(is.null(rawData()) | is.null(input$channeltab)){return ()}
plotSingle(rawData(), input$channeltab)
})
}
You see we set an id
on the tabsetPanel
we create. We can then use that as input
to determine which panel is selected and show the correct plot. All run with
shinyApp(ui = ui, server = server)
How to add dynamic contents under those tabs create using renderUI in shinyR application
Try this
library(shiny)
library(plyr)
library(dplyr)
library(rlang)
library(DT)
ui <- pageWithSidebar(
headerPanel = headerPanel('data'),
sidebarPanel = sidebarPanel(fileInput(
'mtcars', h4('Uplaodmtcardata in csv format')
),
uiOutput('tabnamesui')),
mainPanel(uiOutput("tabsets"))
)
server <- function(input, output, session) {
mtcarsFile <- reactive({input$mtcars})
xxmtcars <-
reactive({
read.table(
file = mtcarsFile()$datapath,
sep = ',',
header = T,
stringsAsFactors = FALSE
)
})
tabsnames <- reactive({
names(xxmtcars())
})
output$tabnamesui <- renderUI({
req(mtcarsFile())
selectInput(
'tabnamesui',
h5('Tab names'),
choices = as.list(tabsnames()),
multiple = T
)
})
tabnamesinput <- reactive({
input$tabnamesui
})
output$tabsets <- renderUI({
req(mtcarsFile())
tabs <-
reactive({
lapply(tabnamesinput(), function(x)
tabPanel(title = basename(x), dataTableOutput(x)))
})
do.call(tabsetPanel, c(tabs()))
})
observe(
lapply(tabnamesinput(), function(x) {
output[[x]] <- DT::renderDataTable({
t<-as.data.frame(dplyr::select(xxmtcars(), !! sym(x)) )
print(t)
datatable(t)
})
})
)
}
runApp(list(ui = ui, server = server))
R Shiny dynamic multilevel/nested tabPanel with renderUI
The answers is quite simple: just put the innerlevel tabsetPanel wihtin renderUI
renderUI({
do.call(tabsetPanel,
lapply(1:length(input$numbers), function(j) {
tabPanel(input$numbers[j],
h5('test'))
}))
})
This will prevent updating/refresing the selectizeInput (numbers)
How do I make dynamic shiny tabs with their own content?
I would like to thank all the good people over at stackoverflow for aiding me in solving this problem; this is the most supportive site for programming beginners out there.
UI:
library(shiny)
shinyUI(navbarPage("TiGr",
tabPanel("File Input Page",
fluidPage("Input")),
tabPanel("Summary Statistics and Plots",
fluidPage("Statistics")),
tabPanel("Time Clusters",
fluidPage("cluster"),
actionButton("subClust", label = "Create Subcluster"),
uiOutput("tabs"),
conditionalPanel(condition="input.level==1",
helpText("test work plz")
),
conditionalPanel(condition="input.level==5",
helpText("hohoho")
)
)
))
Server:
library(shiny)
shinyServer(function(input, output,session) {
output$tabs=renderUI({
Tabs<-as.list(rep(0,input$subClust+1))
for (i in 0:length(Tabs)){
Tabs[i]=lapply(paste("Layer",i,sep=" "),tabPanel,value=i)
}
#Tabs <- lapply(paste("Layer",0:input$subClust,sep=" "), tabPanel)
do.call(tabsetPanel,c(Tabs,id="level"))
})
}
)
Dynamic tabs and checkbox group in R shiny with renderUI
library(shiny)
df <- data.frame(
"Group" = c("Group A", "Group B", "Group A", "Group A", "Group B"),
"Name" = c("Bob", "Paul", "Peter", "Emma", "John"),
"Value" = seq(1,10, length.out=5),
stringsAsFactors = F
)
# UI
ui <- fluidPage(
mainPanel(
uiOutput('mytabs')
)
)
# SERVER
server <- function(input, output) {
Tabs_titles = unique(df$Group)
output$mytabs <- renderUI({
myTabs <- lapply(Tabs_titles,
function(x){
tabPanel(title = x,
checkboxGroupInput(inputId = paste0("checkboxID_", x),
label = "My Checkbox",
choices = df %>% subset(Group == x) %>% pull(Name),
selected = df %>% subset(Group == x) %>% pull(Name)
),
tableOutput(paste0("my_Table_", x))
)
}
)
do.call(tabsetPanel, myTabs)
})
observe(
lapply(Tabs_titles,
function(x){
checked_names <- reactive({input[[paste0("checkboxID_", x)]]})
output[[paste0("my_Table_", x)]] <-renderTable({
df %>%
subset(Group == x & Name %in% checked_names())
})
}
)
)
}
shinyApp(ui, server)
Related Topics
Call Apply-Like Function on Each Row of Dataframe With Multiple Arguments from Each Row
Gradient of N Colors Ranging from Color 1 and Color 2
Putting Mathematical Symbols and Subscripts Mixed With Regular Letters
How to Read a CSV File in R With Different Number of Columns
R - Concatenate Two Dataframes
What's Wrong With My Function to Load Multiple .Csv Files into Single Dataframe in R Using Rbind
Generate a Sequence of the Last Day of the Month Over Two Years
R Shiny: Handle Action Buttons in Data Table
How to Efficiently Calculate Distance Between Pair of Coordinates Using Data.Table :=
Create Group Number For Contiguous Runs of Equal Values
How to Unload a Package Without Restarting R
As.Date With Dates in Format M/D/Y in R
What Is the Purpose of Setting a Key in Data.Table
Using Regex in R to Find Strings as Whole Words (But Not Strings as Part of Words)
Adding a New Column to Each Element in a List of Tables or Data Frames