Home > Net >  Shiny: Assigning different dataframe names in if-else statement
Shiny: Assigning different dataframe names in if-else statement

Time:01-06

I have reactive tables df1, df2 from Shiny. After some preprocessing I saved them as df1_a, df1_b, df1_a_grouped.

I have an if-else statement defined in df3:

if df1_b exists, then add 10 to column num1 else left_join(df2(), df_a_grouped()).

The script works. However, I would like to reference the two reactive dataframes defined in the if-else statement separately from df3 e.g., save as test1 for if else save as test2 so that I could use each of these in another if-else

Any help would be of great help.

Below is a fully reproducible sample script:

#### Libraries
library(shiny)
library(shinyWidgets)
library(tidyr)
library(dplyr)
library(shinydashboard)
library(reactable)


#### ui
ui <- dashboardPage(
  dashboardHeader(title = "Skew"),
  
  sidebar <- dashboardSidebar(
    sidebarMenu(
      menuItem("Test1", tabName = "tab1", icon = icon("table"))
    )
  ),
  
  body <- dashboardBody(
    shinyjs::useShinyjs(),
    
    tabItems(
      tabItem(
        tabName = "tab1",
        
        fluidRow(
          
          ## df1
          reactableOutput("table1"),
          
          br(),
          br(),
          
          ## df2
          reactableOutput("table2"),
          
          br(),
          br(),
          
          ## df3
          reactableOutput("table3")
          
          
          
        ) # fluidRow
        
      ) # tab1 - tabItem
    ) # tabItems
    
  ) # dashboardBody
) # dashboardPage




#### server @
server <- function(input, output, session) {
  
  ## df1
  # reactive
  df1 <- reactive({
    data.frame(
      # "id" = c("A", "A", "A", "B"),
      "id" = c("A", "A", "A", "A"),
      "num1" = c(10, 11, 12, 13)
    )
  })
  
  # renderReactable
  output$table1 <- renderReactable({
    reactable(df1(), borderless = F, defaultColDef = colDef(align = "center"))
  })
  
  ## df2
  # reactive
  df2 <- reactive({
    data.frame(
      "id" = c("A", "A", "B"),
      "num2" = c(14, 15, 16)
    )
  })
  
  # renderReactable
  output$table2 <- renderReactable({
    reactable(df2(), borderless = F, defaultColDef = colDef(align = "center"))
  })
  
  ## df1_a
  # reactive
  df1_a <- reactive({
    df1() %>% filter(id == "A")
  })
  
  ## df1_b
  # reactive
  df1_b <- reactive({
    df1() %>% filter(id == "B")
  })
  
  ## 
  df1_a_grouped <- reactive({
    df1_a() %>%
      group_by(id) %>%
      summarise(
        sum_num1 = sum(num1)
      )
  })
  
  ## df3
  # reactive
  # would like to reference the two dataframes separately
  df3 <- reactive({
    if (nrow(df1_b()) > 0) {
      df <- df1_b() %>% mutate(num1_addten = num1   10) # test1
    } else {
      df <- left_join(df2(), df 1 _a_grouped(), on = "id") # test2
    }
    return(df)
  })
  
}

shinyApp(ui, server)

CodePudding user response:

There are many ways to store reactive elements. You could make df3 a reactive object storing a list with your different dataframes:

df3 <- reactive({
    if (nrow(df1_b()) > 0) {
      df1 <- df1_b() %>% mutate(num1_addten = num1   10) # test1
    } else {
      df1 <- left_join(df2(), df1_a_grouped(), on = "id") # test2
    }
    df2 <- df1_b() %>% mutate(num1_addten = num1   10)
    df3 <- left_join(df2(), df1_a_grouped(), on = "id")
    list(df1, df2, df3)
  })

Then you can call them like this:

  df3()[[1]]
  df3()[[2]]
  df3()[[3]]
  • Related