Search code examples
rif-statementggplot2shinyshiny-server

Shiny if else statement


I am having problems using conditional statements in Shiny. I want the user select number of variable. If choose 1 variable then plot chart of 1 variable (ex density plot), if choose 2 variable then plot chart of 2 variables (ex scatter plot). I have tried a few ways, but the output is not as my expected. How can i use if else statement in Shiny server? Tks

UI

   df <- mtcars
    ui <- fluidPage(
        h1("My first app",
           style = 'color: green;
           font-style: italic'),
        hr(),
        fluidRow(
            sidebarPanel(
                radioButtons(inputId = "number",
                             label = "Select number of variable",
                             choices = c("1 variable" = 1,
                                         "2 variable" = 2)),
                selectInput(inputId = "x",
                            label = "Variable 1",
                            choices = names(df)),
                conditionalPanel(
                    condition = "input.number == 2",
                    selectInput(inputId = "y",
                                label = "Variable 2",
                                choices = names(df))
                    ) 
                ),
            column(8, plotOutput("plot"))
        ),
        hr(),
        plotOutput("plot") )

Server

server <- function(input, output, session){
    observeEvent(input$x, 
                 {updateSelectInput(session,
                                    inputId = "y",
                                    label = "Variable 2",
                                    choices = names(df)[names(df) != input$x])
                 })
    
    data <- reactive({
        if(input$number == 1){
            data <- df %>% 
                select(input$x)
        } else {
            data <- df %>% 
                select(input$x, input$y)
        }
    })
    
    output$plot <- renderPlot({
        if(input$number == 1){
            ggplot(data = data(),
                   x = get(input$x))+
                geom_density()
        } else {
            ggplot(data = data,
                   x = get(input$x),
                   y = get(input$y)) +
                geom_point()
        }
    })
}

shinyApp(ui = ui, server = server)

Solution

  • You can try the following code -

    • plotOutput("plot") was mentioned twice, removed it to include it only once.
    • We don't need to check for conditions while creating the dataset in reactive, handle it in the plot code itself.
    • Use .data to refer column names in ggplot code.
    library(shiny)
    library(ggplot2)
    
    df <- mtcars
    ui <- fluidPage(
      h1("My first app",
         style = 'color: green;
               font-style: italic'),
      hr(),
      fluidRow(
        sidebarPanel(
          radioButtons(inputId = "number",
                       label = "Select number of variable",
                       choices = c("1 variable" = 1,
                                   "2 variable" = 2)),
          selectInput(inputId = "x",
                      label = "Variable 1",
                      choices = names(df)),
          conditionalPanel(
            condition = "input.number == 2",
            selectInput(inputId = "y",
                        label = "Variable 2",
                        choices = names(df))
          ) 
        ),
        column(8, plotOutput("plot"))
      )
    )
    
    
    server <- function(input, output, session){
      
      data <- reactive({
        df
      })
    
     observeEvent(input$x, 
                   {updateSelectInput(session,
                                      inputId = "y",
                                      label = "Variable 2",
                                      choices = names(df)[names(df) != input$x])
                   })
      
      output$plot <- renderPlot({
        
        if(input$number == 1){
          plot <- ggplot(data = data(), aes(x = .data[[input$x]])) + geom_density()
        } else {
          plot <- ggplot(data = data(),
                 aes(x = .data[[input$x]], y = .data[[input$y]])) +
            geom_point()
        }
        plot
      })
    }
    
    shinyApp(ui = ui, server = server)