R Shiny:读取CSV并使用dplyr和ggplot保存在变量中

时间:2018-08-21 18:50:21

标签: r shiny

我正在尝试将文件输入添加到我的R Shiny程序中,用户可以将自己的CSV / Excel文件添加到其中,但是我遇到了一些问题。

如果我运行直接从PC读取CSV的代码(没有fileInput),我没有问题,但是任何时候尝试输入它都会出错。

我已经做了一些研究,并试图复制我在网上看到的内容,但是他们的解决方案对我不起作用。我已经看过this postthis post,但是它们的方法不起作用。还是我做错了。

ui <- fluidPage(

  theme = 'custom.css',

  dashboardPage(
    dashboardHeader(title = 'Student Grades'),
    dashboardSidebar(
      fileInput(inputId = 'file', label = 'Select a file...'),
      selectInput(inputId = 'periodVar', 
                  label = 'Select Period',
                  choices = unique(grades$Period)),
      uiOutput('secondSelection'),
      dataTableOutput('individualSummary'),
      img(src='lhimg.JPG', width = '100%')
                    ),

    dashboardBody(
      useShinyjs(),
      tabsetPanel(
        tabPanel(
          'Test',
          tableOutput('contents')
                ),
        tabPanel(
          'Graph',
          plotOutput('individualGraph')
                )
          )
    )
  )
)

server <- function(input, output, session) {

  # grades <- eventReactive(input$file, {
  #   read.csv(input$file$datapath)
  # })

  grades2 <- reactive({
    inFile <- input$file
    if (is.null(inFile))
      return(NULL)
    myTbl <- read.csv(inFile$datapath)
    return(myTbl)
  })

  # observe({
  #   grades2 = input$file
  #   if (is.null(file)) {
  #     return(NULL)
  #   }
  #   grades2 = read.csv(grades2$datapath)
  # })

  tidyGrades <- function(data){
    data %>% 
      gather(key = Type, value = Grade, (c('Test', 'Quiz', 'Homework')), na.rm = T) %>% 
      arrange(Period, Student,Date, Type) %>% 
      mutate(Weight = ifelse(Type == 'Homework', 30, 
                             ifelse(Type == 'Quiz', 20, 50)),
             Date = mdy(Date))
  }

  weightedMeanDf <- tidyGrades(grades2)

我的代码有一个小片段。如果需要,我可以发布整个内容,但我不想在寻求帮助时很难阅读。 weightedMeanDf只是我需要做的一件事,但是我还需要生成一些其他图形和表格。注释的代码是我根据在线解决方案尝试的不同方法。我最近得到的是在服务器函数内使用未注释的代码(第一反应式)函数。

但是我得到了这个错误:

  Error in UseMethod("gather_") : 
  no applicable method for 'gather_' applied to an object of class "c('reactiveExpr', 'reactive')" 

我真的很茫然,现在我的想法已经用完了。也许我是完全错误的方法。也许最好的方法是对创建的每个图和数据框使用反应函数?我觉得那样只会降低所有内容的速度,而不是一次读取csv文件,然后根据第一次读取结果生成图形和绘图?

1 个答案:

答案 0 :(得分:0)

这个怎么样?

library(shiny)
library(digest)

# Create data to read
write.csv(file="~/iris.csv",iris)

shinyApp(ui=shinyUI(
  fluidPage(
    sidebarLayout(
      sidebarPanel(
        textInput("path","Enter path: "),
        actionButton("readFile","Read File"),
        tags$hr()
      ),
      mainPanel(
        tableOutput('contents')
      )))
),
server = shinyServer(function(input,output,session){
  file <- reactiveValues(path=NULL,md5=NULL,rendered=FALSE)

  # Read file once button is pressed
  observeEvent(input$readFile,{
    if ( !file.exists(input$path) ){
      print("No such file")
      return(NULL)
    }
    tryCatch({
      read.csv(input$path)
      file$path <- input$path
      file$md5  <- digest(file$path,algo="md5",file=TRUE)
      file$rendered <- FALSE
    },
    error = function(e) print(paste0('Error: ',e)) )
  })

  observe({
    invalidateLater(1000,session)
    print('check')

    if (is.null(file$path)) return(NULL)

    f   <- read.csv(file$path)
    # Calculate ckeksum
    md5 <- digest(file$path,algo="md5",file=TRUE)

    # If no change in cheksum, do nothing
    if (file$md5 == md5 && file$rendered == TRUE) return(NULL)

    output$contents <- renderTable({

      print('render')
      file$rendered <- TRUE
      f
    })
  })

}))