当 select 来自 R shinydashbard 中上传数据集的变量时,ggplot2 发生变异错误

ggplot2 mutate error when select variable from uploaded dataset in R shinydashbard

我正在尝试在 R shiny 中使用 ggplot 绘图。我想上传数据,任何变量都可以用于绘图。我试图保持 aes() 动态。我尝试了几个例子 example 1,但对我来说很管用。这是我的代码:

library(shiny)
library(shinydashboard)
library(readxl)
library(DT)
library(dplyr)
library(ggplot2)
# Define UI for application that draws a histogram
ui <- fluidPage(
  titlePanel("Uploading Files"),
  sidebarLayout(
    sidebarPanel(
      fileInput('file1', 'Upload data File',
                accept=c('text/csv','.xlsx', 
                         'text/comma-separated-values,text/plain', 
                         '.csv'))),
      mainPanel(
        DT::dataTableOutput('contents')
      )
    ),
  tabPanel("First Type",
           pageWithSidebar(
             headerPanel('Visualization of Dengue Cases'),
             sidebarPanel(
               
              
               selectInput('xcol', 'X Variable', ""),
               selectInput('ycol', 'Y Variable', "", selected = "")
               
             ),
             
             mainPanel(
               plotOutput('MyPlot')
             )
           )
  )
  )
  
       
       
# Define server logic required to draw a histogram
server <- function(input, output,session) {

  data <- reactive({ 
    req(input$file1) 
    
    inFile <- input$file1 
    
    
    df <- read_excel(paste(inFile$datapath,  sep=""), 1)
    
    
    
    
    updateSelectInput(session, inputId = 'xcol', label = 'X Variable',
                      choices = names(df), selected = names(df))
    updateSelectInput(session, inputId = 'ycol', label = 'Y Variable',
                      choices = names(df), selected = names(df)[2])
    
    return(df)
  })
  
  output$contents <- DT::renderDataTable({
    data()
  },options = list(pageLength = 10, width="100%", scrollX = TRUE))
  
  
  output$MyPlot <- renderPlot({
    select_quo <- quo(input$MyPlot_select)
    
    data %>%
      mutate(user_input = !!select_quo) %>%
      ggplot(aes(fill=user_input,  y=user_input, x= user_input)) + 
      geom_bar( stat="identity")
    
    })
}
# Run the application 
shinyApp(ui = ui, server = server)

可以使用任何数据集,比如Diamond dataset。 也请帮助允许所有类型的格式 (.csv, .txt,.xls) 数据。截至目前,只有 .xls 是可以接受的。

您的代码存在几个问题。

  1. 您在 renderPlot
  2. 中使用 data 而不是 data()
  3. 没有输入input$MyPlot_select
  4. 使用quo!! 不会得到想要的结果。相反,如果您的列名称是字符串,您可以简单地使用 .data 代词。
  5. renderPlot开头添加req

这表示您的 renderPlot 应该是这样的:

output$MyPlot <- renderPlot({
    req(input$xcol, input$ycol)

    x <- input$xcol
    y <- input$ycol
    fill <- input$xcol
    
    ggplot(data(), aes(x = .data[[x]], y = .data[[y]], fill=.data[[fill]])) + 
      geom_col()
  })

对于你问题的第二部分。为了使您的应用程序适用于不同类型的输入文件,您可以使用例如获取文件扩展名tools::file_ext 并在 switch 语句中使用结果。

完整的可重现代码:

library(shiny)
library(shinydashboard)
library(readxl)
library(DT)
library(dplyr)
library(ggplot2)

ui <- fluidPage(
  titlePanel("Uploading Files"),
  sidebarLayout(
    sidebarPanel(
      fileInput("file1", "Upload data File",
        accept = c(
          "text/csv", ".xlsx",
          "text/comma-separated-values,text/plain",
          ".csv"
        )
      )
    ),
    mainPanel(
      DT::dataTableOutput("contents")
    )
  ),
  tabPanel(
    "First Type",
    pageWithSidebar(
      headerPanel("Visualization of Dengue Cases"),
      sidebarPanel(
        selectInput("xcol", "X Variable", ""),
        selectInput("ycol", "Y Variable", "", selected = "")
      ),
      mainPanel(
        plotOutput("MyPlot")
      )
    )
  )
)



# Define server logic required to draw a histogram
server <- function(input, output, session) {
  data <- reactive({
    req(input$file1)

    inFile <- input$file1

    type <- tools::file_ext(inFile$name)
    
    filename <- inFile$datapath
    
    df <- switch(type,
                 "xlsx" = read_excel(filename),
                 "csv" = read_csv(filename),
                 "tsv" = read_tsv(filename))
    
    updateSelectInput(session,
      inputId = "xcol", label = "X Variable",
      choices = names(df), selected = names(df)
    )
    updateSelectInput(session,
      inputId = "ycol", label = "Y Variable",
      choices = names(df), selected = names(df)[2]
    )

    return(df)
  })

  output$contents <- DT::renderDataTable({
      data()
    }, options = list(pageLength = 10, width = "100%", scrollX = TRUE))

  output$MyPlot <- renderPlot({
    req(input$xcol, input$ycol)

    x <- input$xcol
    y <- input$ycol
    fill <- input$xcol
    
    ggplot(data(), aes(x = .data[[x]], y = .data[[y]], fill=.data[[fill]])) + 
      geom_col()
  })
}
# Run the application
shinyApp(ui = ui, server = server)