闪亮的 if else 语句

时间:2021-07-12 06:28:15

标签: r if-statement shiny shiny-server

我在 Shiny 中使用条件语句时遇到问题。我希望用户选择变量数。如果选择 1 个变量,则绘制 1 个变量的图表(例如密度图),如果选择 2 个变量,则绘制 2 个变量的图表(例如散点图)。我尝试了几种方法,但输出并不符合我的预期。如何在 Shiny 服务器中使用 if else 语句? tks

界面

   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 <- 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)

2 个答案:

答案 0 :(得分:2)

您可以使用 aes_string
另一个非常重要的点是 UI 中的 never to use the same output twice

df <- mtcars
library(ggplot2)
library(dplyr)

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() 
  # Never use output twice : the UI won't work!
  #plotOutput("plot") 
  )

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({
    cat(input$x)
    if(input$number == 1){
      ggplot(data = data())+
        geom_density(aes_string(x=input$x))
    } else {
      ggplot(data = data()) +
        geom_point(aes_string(x=input$x,y=input$y))
    }
  })
}

shinyApp(ui = ui, server = server)

答案 1 :(得分:1)

你可以试试下面的代码-

  • plotOutput("plot") 被提及两次,将其删除以只包含一次。
  • 我们不需要在 reactive 中创建数据集时检查条件,而是在绘图代码本身中处理它。
  • 使用 .data 在 ggplot 代码中引用列名。
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)