Conditional VerbatimTextOutput


#1

I want to have a conditional verbatimTextOutput but so far I just receive an error. In this reproducible example I want the numbers that belong to region or subregion to be listed in the panel. I achieve what I want if I just do it separately but I do not want both displayed simultaneously. If anyone can help, thanks!

library(shiny)
library(tidyverse)




sample_df <- data.frame(
  region = as.character(c("North", "North", "North",
             "South","South","South",
             "West", "West", "West",
             "East", "East","East",
             "Central","Central", "Central",
             "North", "North", "North",
             "South","South","South",
             "West", "West", "West",
             "East", "East","East",
             "Central","Central", "Central",
             "North", "North", "North",
             "South","South","South",
             "West", "West", "West",
             "East", "East","East",
             "Central","Central", "Central",
             "North", "North", "North",
             "South","South","South",
             "West", "West", "West",
             "East", "East","East",
             "Central","Central", "Central",
             "North", "North", "North",
             "South","South","South",
             "West", "West", "West",
             "East", "East","East",
             "Central","Central", "Central",
             "North", "North", "North",
             "South","South","South",
             "West", "West", "West",
             "East", "East","East",
             "Central","Central", "Central"
  )),
  subregion = as.character(c("NorthWest", "North", "NorthCentral",
                "SouthWest", "SouthEast", "SouthCentral",
                "WestSouth", "WestEast", "WestCentral",
                "East", "East", "EastCentral",
                "CentralWest", "Central East", "CentralCentral",
                "NorthWest", "NorthEast", "North",
                "SouthWest", "SouthEast", "SouthCentral",
                "WestSouth", "WestEast", "WestCentral",
                "EastSouth", "EastEast", "EastCentral",
                "CentralWest", "Central East", "CentralCentral",
                "North", "North", "North",
                "SouthWest", "SouthEast", "SouthCentral",
                "WestSouth", "WestEast", "WestCentral",
                "EastSouth", "EastEast", "EastCentral",
                "CentralWest", "Central East", "CentralCentral",
                "NorthWest", "NorthEast", "NorthCentral",
                "SouthWest", "SouthEast", "SouthCentral",
                "WestSouth", "WestEast", "WestCentral",
                "EastSouth", "EastEast", "EastCentral",
                "Central", "Central East", "CentralCentral",
                "NorthWest", "NorthEast", "NorthCentral",
                "SouthWest", "SouthEast", "SouthCentral",
                "WestSouth", "WestEast", "WestCentral",
                "EastSouth", "EastEast", "EastCentral",
                "CentralWest", "Central", "Central",
                "NorthWest", "NorthEast", "NorthCentral",
                "SouthWest", "South", "South",
                "WestSouth", "WestEast", "WestCentral",
                "EastSouth", "EastEast", "EastCentral",
                "CentralWest", "Central East", "CentralCentral"
  )),
  numbers = as.character(c("25688", "00000", "56489",
              "25688", "56489", "45866",
              "45586","89626", "22635", 
              "00000", "00000", "25381",
              "25688", "56489", "45866",
              "45586","89626", "00000",
              "25188", "56489", "42266",
              "42286","83326", "22635",
              "25688", "53389", "45866",
              "45186","89626", "22115",
              "00000","00000","00000",
              "25188", "56489", "42266",
              "42286","83326", "22635",
              "25688", "53389", "45866",
              "45186","89626", "22115",
              "25188", "56489", "42266",
              "42286","83326", "22635",
              "25688", "53389", "45866",
              "45186","89626", "22115",
              "00000", "54884", "15653",
              "23188", "56289", "41266",
              "42286","13326", "22635",
              "21688", "51389", "31866",
              "45181","89616", "22125",
              "45821", "00000", "00000",
              "25188", "56489", "42266",
              "42286","00000", "00000",
              "25688", "53389", "45866",
              "45186","89626", "22115",
              "25188", "56489", "42266"
              ))
)


sample_df$region <- as.character(sample_df$region)
sample_df$subregion <-as.character(sample_df$subregion)
sample_df$numbers <-as.character(sample_df$numbers)


ui <- fluidPage(
  mainPanel(
    selectInput("region", "Region: ", c("", sample_df$region)),
    uiOutput("sub"),
    verbatimTextOutput("text")
  )
)


server <- function(input,output,session){
  Data1 <- reactive({
    q <- sample_df %>% filter(region==input$region) %>% filter(numbers != "00000")
    q$subregion %>% unique()
  })
  
  
  output$sub <- renderUI({
    conditionalPanel( condition = "input.region !== null && input.region !== ''",
                      selectInput("subregion", h4(strong("Subregion :")), c("", Data1()), selected="")
    )
  })
  
  list1 <- reactive({
    v <- sample_df %>% filter(region == input$region) %>% filter(numbers != "00000")
    v$numbers %>% unique()
  })

  list2 <- reactive({
    v <- sample_df %>% filter(subregion == input$subregion) %>% filter(numbers != "00000")
    v$numbers %>% unique()

  })
  
  output$text <- renderPrint({
    if(nrow(list1()) >0 && nrow(list2()) == 0){
    cat(list1(), sep = "\n")
    }else if(nrow(list2())> 0){
      cat(list2(), sep = "\n")
    }
  })
}
shinyApp(ui,server)

EDIT:

I realized in this case that I should not have used nrow but I should have used length instead because I was working with reactive vectors not tables. Minor mistake I just noticed. Therefore I should have the following:

  output$text <- renderPrint({
    if(length(list1()) >0 && length(list2()) == 0){
    cat(list1(), sep = "\n")
    }else if(length(list2())> 0){
      cat(list2(), sep = "\n")
    }
  })

Hopefully this helps anyone has similar issues with their Shiny code. Thanks!


#2

Is there a reason you're trying to render a text object and not a table?


#4

I'm new to Shiny so I was not aware it could be output as a table. I tried to render as a datatable but it had the data table format but I wanted cleaner output that just lists the items.
Does renderTable work in that way for this example?


#5

Your sample_df table is a data frame and it appears you want to

  1. Apply some dynamic filtering and
  2. Visualize the subset information

Data table will render a table object similar to what you see in Excel. This is the standard convention of viewing tabular data. It can even be directly selected, copied, and pasted into Excel.


#6

Okay, I edited my code for a table output but I still receive an error for rendering the table through the "if" statements...

library(shiny)
library(tidyverse)

sample_df <- data.frame(
  region = as.character(c("North", "North", "North",
             "South","South","South",
             "West", "West", "West",
             "East", "East","East",
             "Central","Central", "Central",
             "North", "North", "North",
             "South","South","South",
             "West", "West", "West",
             "East", "East","East",
             "Central","Central", "Central",
             "North", "North", "North",
             "South","South","South",
             "West", "West", "West",
             "East", "East","East",
             "Central","Central", "Central",
             "North", "North", "North",
             "South","South","South",
             "West", "West", "West",
             "East", "East","East",
             "Central","Central", "Central",
             "North", "North", "North",
             "South","South","South",
             "West", "West", "West",
             "East", "East","East",
             "Central","Central", "Central",
             "North", "North", "North",
             "South","South","South",
             "West", "West", "West",
             "East", "East","East",
             "Central","Central", "Central"
  )),
  subregion = as.character(c("NorthWest", "North", "NorthCentral",
                "SouthWest", "SouthEast", "SouthCentral",
                "WestSouth", "WestEast", "WestCentral",
                "East", "East", "EastCentral",
                "CentralWest", "Central East", "CentralCentral",
                "NorthWest", "NorthEast", "North",
                "SouthWest", "SouthEast", "SouthCentral",
                "WestSouth", "WestEast", "WestCentral",
                "EastSouth", "EastEast", "EastCentral",
                "CentralWest", "Central East", "CentralCentral",
                "North", "North", "North",
                "SouthWest", "SouthEast", "SouthCentral",
                "WestSouth", "WestEast", "WestCentral",
                "EastSouth", "EastEast", "EastCentral",
                "CentralWest", "Central East", "CentralCentral",
                "NorthWest", "NorthEast", "NorthCentral",
                "SouthWest", "SouthEast", "SouthCentral",
                "WestSouth", "WestEast", "WestCentral",
                "EastSouth", "EastEast", "EastCentral",
                "Central", "Central East", "CentralCentral",
                "NorthWest", "NorthEast", "NorthCentral",
                "SouthWest", "SouthEast", "SouthCentral",
                "WestSouth", "WestEast", "WestCentral",
                "EastSouth", "EastEast", "EastCentral",
                "CentralWest", "Central", "Central",
                "NorthWest", "NorthEast", "NorthCentral",
                "SouthWest", "South", "South",
                "WestSouth", "WestEast", "WestCentral",
                "EastSouth", "EastEast", "EastCentral",
                "CentralWest", "Central East", "CentralCentral"
  )),
  numbers = as.character(c("25688", "00000", "56489",
              "25688", "56489", "45866",
              "45586","89626", "22635", 
              "00000", "00000", "25381",
              "25688", "56489", "45866",
              "45586","89626", "00000",
              "25188", "56489", "42266",
              "42286","83326", "22635",
              "25688", "53389", "45866",
              "45186","89626", "22115",
              "00000","00000","00000",
              "25188", "56489", "42266",
              "42286","83326", "22635",
              "25688", "53389", "45866",
              "45186","89626", "22115",
              "25188", "56489", "42266",
              "42286","83326", "22635",
              "25688", "53389", "45866",
              "45186","89626", "22115",
              "00000", "54884", "15653",
              "23188", "56289", "41266",
              "42286","13326", "22635",
              "21688", "51389", "31866",
              "45181","89616", "22125",
              "45821", "00000", "00000",
              "25188", "56489", "42266",
              "42286","00000", "00000",
              "25688", "53389", "45866",
              "45186","89626", "22115",
              "25188", "56489", "42266"
              ))
)


sample_df$region <- as.character(sample_df$region)
sample_df$subregion <-as.character(sample_df$subregion)
sample_df$numbers <-as.character(sample_df$numbers)


ui <- fluidPage(
  mainPanel(
    selectInput("region", "Region: ", c("", sample_df$region)),
    uiOutput("sub"),
    tableOutput("table")
  )
)


server <- function(input,output,session){
  Data1 <- reactive({
    q <- sample_df %>% filter(region==input$region) %>% filter(numbers != "00000")
    q$subregion %>% unique()
  })
  
  
  output$sub <- renderUI({
    conditionalPanel( condition = "input.region !== null && input.region !== ''",
                      selectInput("subregion", h4(strong("Subregion :")), c("", Data1()), selected="")
    )
  })
  
  list1 <- reactive({
    v <- sample_df %>% filter(region == input$region) %>% filter(numbers != "00000")
    v$numbers %>% unique()
  })

  list2 <- reactive({
    v <- sample_df %>% filter(subregion == input$subregion) %>% filter(numbers != "00000")
    v$numbers %>% unique()

  })
  
  output$table<- renderTable({
    if(nrow(list1()) >0 && nrow(list2()) == 0){
    list1()
    }else if(nrow(list2())> 0){
      list2()
    }
  })
}
shinyApp(ui,server)

#7

Okay so I figured out that my problem was that my reactive list1 and list2 were vectors and not data tables. Thus I converted the output to a table and it works perfectly now!

  list1 <- reactive({
    v <- sample_df %>% filter(region == input$region) %>% filter(numbers != "00000")
    v$numbers %>% unique() %>% as.tibble()
  })

  list2 <- reactive({
    v <- sample_df %>% filter(subregion == input$subregion) %>% filter(numbers != "00000")
    v$numbers %>% unique() %>% as.tibble()

  })