首页 > 解决方案 > 从 Excel 工作表中获取 colnames 的响应式应用程序,以供 Shiny 应用程序选择将哪一列放入 ggplot

问题描述

TL;DR,这是我的第一个 Shiny 应用程序,我被困在这个反应性问题上。

我正在编写一个 Shiny 应用程序,它将获取 Excel 调查数据并将其放入 ggplot 函数中。该功能应该可以工作,但调查问题每年都会有所不同。我希望应用程序执行以下操作:

  1. 获取多个 Excel 文件并阅读它们
  2. 显示组织名称、志愿者人数/小时数和调查年份的三个下拉菜单,并显示 X 和 Y 标签和标题的三个文本输入表格
  3. 打印一个直方图,显示每个组织在该组织出现的每一年中带有闪避条的志愿者数量。

问题在于第二个任务。我希望应用程序在文件上传时做出反应,方法是将整个 colnames() 列表放入下拉菜单中,供用户选择哪些列具有组织名称。我已经尝试过 Stack Overflow 上其他问题的解决方案,但最终都抛出了错误。

这是我的用户界面和服务器代码:


library(rsconnect)
library(readxl)
library(shiny)
library(ggplot2)



dataset <- file

ui <- fluidPage(
  shinythemes::themeSelector(),
  titlePanel("Volunteer stats"),

  sidebarLayout(

    sidebarPanel(
      #I need: names of each of the files, 
      #   columns for org, num_vol, and survey year, 
      #   labels for x axis, y axis, and title, 
      #   name for the PDF to be created

    fileInput(inputId = "file", label = "Choose Excel file", multiple = TRUE),
    uiOutput("org_select"),
    uiOutput("num_select"),
    uiOutput("year_select"),
    textInput(inputId = "org_label", label = "X axis label"), 
    textInput(inputId = "vols_label", label = "Y axis label"), 
    textInput(inputId = "plot_title", label = "Chart title"),
    textInput(inputId = "pdf_title", label = "PDF title")), 

  mainPanel(
    plotOutput(
      outputId = "histogram"
  )
  )
))

server <- function(input, output) {

  output$org_select <- renderUI({
        selectInput("org_col", "Which column has the organization name?", choices = list(colnames(read_excel(input$file))), label = "Organization")
  })
  output$num_select <- renderUI({
    selectInput("num_vols", "Which column has the relevant metric?", choices = list(colnames(read_excel(input$file))), label = "Number of Volunteers")
  })
  output$year_select <- renderUI({
    selectInput("year", "Which column has the year?", choices = list(colnames(read_excel(input$file))), label = "Year")
  })

#assemble all the files into a list based on the input, to be passed to ggplot (not shown) 
  getData <- reactive({
    if (is.null(input$file)){
      return(NULL)
    }else{
      numfiles = nrow(input$file)
      files_list = list(
        for(i in 1:numfiles)
        {
          XL_file = read_excel(input$file[[i, 'datapath']], header = TRUE)
          lastrow = nrow(XL_file)
          shift = function(x, n){
            c(x[-(seq(n))], rep(NA, n)) 
          }
          XL_file$identity = shift(XL_file$identity, 1)
          files_list[[i]] = XL_file[-lastrow, ]
        }
      )
    }
  })
getData()
shinyApp(ui = ui, server = server)

为简洁起见,我没有包含我的 ggplot 函数。如果我需要这方面的帮助,我稍后会提交一个单独的问题。

非常感谢,无畏

标签: rexcelggplot2shinyreactive

解决方案


只需两个小修复即可使其正常工作:

input$file是一个对象(如果需要,也可以是列表),但需要read_excel()一个包含文件路径的字符串。使用input$file$datapath.

choices参数期望命名或未命名值的命名列表。随着list(colnames(...))您向它传递一个列表,其中包含一个包含 chioices 的元素:

list(colnames(read_excel('path/to/file')))
[[1]]
[1] "COL_1"      "COL_2"             "COL_3"           "COL_4"   

只需将它传递给colnames().

server <- function(input, output) {

  output$org_select <- renderUI({
    selectInput("org_col", "Which column has the organization name?", choices = colnames(read_excel(input$file$datapath)), label = "Organization")
  })
  output$num_select <- renderUI({
    selectInput("num_vols", "Which column has the relevant metric?", choices = colnames(read_excel(input$file$datapath)), label = "Number of Volunteers")
  })
  output$year_select <- renderUI({
    selectInput("year", "Which column has the year?", choices = colnames(read_excel(input$file$datapath)), label = "Year")
  })
}

推荐阅读