Dani.0795
Dani.0795

Reputation: 43

How to create a reactive tabsets on Shiny R

I'm doing a Shiny App on R, I want to change a filter depends on the "Regiones", It means, I have a tabsetPanel into a TabPanel,

This is my App now

If I click on "Antioquia" my server.R should be

filter(Base, Base == "Antioquia")

But, If I click on "Bogotá", it should change to

filter(Base, Base == "Bogotá")

And so on... How can I do it?

Upvotes: 2

Views: 2030

Answers (1)

Mike Wise
Mike Wise

Reputation: 22827

The task is to filter a dataframe reactively when the tabpanel changes. This is harder to figure out than one might think.

In order to do that you have to define an id for the tabsetPanel, otherwise there will be nothing to "react" to. Since one normally does not need it, most examples don't have that id field, and thus it can be hard to stumble across. It is not documented in the help under ?tabsetPanel for example.

Here is a minimal example that does what you are looking for.

  • It creates a tabsetPanel with two tabPanels
  • the tabsetPanel has an id called tabx.
  • It defines a dataframe named basedf with two kinds of rows, "A" and "B"
  • A filter value is stored as an element in a reactiveValues variable.
  • It sets that filter when the tab changes (the input$tabx statement is necessary for that to happen, otherwise the built-in reactive caching will cause it to be triggered only once).
  • There is a reactive output field that filters the basedf and prints out what remains.

The code:

library(shiny)
library(dplyr)

basedf <- data.frame(base=c("A","B","A","B","B","A"),val=1:6)

u <- shinyUI(fluidPage(

  titlePanel(h2("TabPanel Test")),
  sidebarLayout(        
    sidebarPanel(
      verbatimTextOutput("out1")
    ),        
    mainPanel(
      tabsetPanel(id="tabx",
        tabPanel("tab A", textOutput("outA")), 
        tabPanel("tab B", textOutput("outB"))
      )
    )
  )
))
s <- shinyServer(function(input,output){
  rv <- reactiveValues(curtab=NULL)

  output$outA <- renderText({
    input$tabx
    rv$curfilt <- "A"
    "this is tab A"
  })
  output$outB <- renderText({
    input$tabx
    rv$curfilt <- "B"
    "this is tab b"
  })
  output$out1 <- renderPrint({
    print(sprintf("curtab:%s",input$tabx))
    print(sprintf("curfilt:%s",rv$curfilt))
    ndf <- filter(basedf,base==rv$curfilt)
    print(ndf)
  })
})
shinyApp(u,s)

And here is what the output looks like: enter image description here

Upvotes: 2

Related Questions