rshinyuioutput

R Shiny: Switch between table and plot in renderUI


I am trying to let the user select the kind of display he wishes, but when I try to render the plot it gives me an error.

Here is the code:

library(shiny)
library(DT)
library(data.table)

runApp(list(
    ui = fluidPage(
        wellPanel(
            radioButtons("visuBtn", NULL, choices = c(Table = "table", Plot = "plot"))
        ),
        wellPanel(
            uiOutput("DataTable")
        )
    ),
    server = function(input, output){

        observeEvent(input$visuBtn,{
            output$DataTable <- renderUI({
                dfconc <- data.table(time = c(1,2,3,4,5), concentration = c(0.1, 0.4, 0.5, 0.7, 0.8))

                if(input$visuBtn == "table"){
                    output$aa <- renderDataTable(dfconc, options = list(paging = FALSE, searching = FALSE))
                    dataTableOutput("aa")
                }
                else { ### NOT WORKING
                    output$aa <- renderPlot({
                        plot(dfconc$time, dfconc$concentration, xlab = "Time", ylab = "Concentration")
                    })
                    fixedRow(
                        plotOutput("aa")
                    )
                }      ###

            })
        })
    }
))


Thanks for your help


Solution

  • I think its better if you render the outputs on the client side and then simply show and hide the elements based on the selection. This way you're not wasting resources on the server side

    library(shiny)
    library(shinyjs)
    library(DT)
    library(data.table)
    
    runApp(list(
      ui = fluidPage(
        useShinyjs(),
        wellPanel(
          radioButtons("visuBtn", NULL, choices = c(Table = "table", Plot = "plot"))
        ),
        wellPanel(
          dataTableOutput("mytable"),
          plotOutput("myplot")
        )
      ),
      server = function(input, output, session){
    
        dfconc <- data.table(time = c(1,2,3,4,5), concentration = c(0.1, 0.4, 0.5, 0.7, 0.8))
    
        output$mytable <- renderDataTable(
          dfconc, options = list(paging = FALSE, searching = FALSE)
        )
    
        output$myplot <- renderPlot({
          plot(dfconc$time, dfconc$concentration, xlab = "Time", ylab = "Concentration")
        })
    
        observeEvent(input$visuBtn,{
          req(input$visuBtn)
          if(input$visuBtn == "plot"){
            hide("mytable")
            show("myplot")
          }else{
            hide("myplot")
            show("mytable")
          }
        })
      }
    ))