1

我正在尝试构建一个闪亮的应用程序,而我以前从未这样做过。

我想要做的是允许用户从用户选择的 CSV 文件上传数据,看起来像这样:

ID    Date        Name        Amount
123   01/12/2018  John Doe    100
124   01/02/2018  Bob Smith   110
125   01/03/2018  Jane Jones  100
126   01/02/2018  John Doe    110
127   01/03/2018  Bob Smith   100
128   01/04/2018  Jane Jones  110
129   01/03/2018  John Doe    100
130   01/04/2018  Bob Smith   110
131   01/04/2018  Jane Jones  120
132   01/14/2018  Tom Thomas  100

然后我想让应用程序使用这些数据来运行如下代码:

as.Date(myDF$Date, format="%m/%d/%Y")
sortedByDate = myDF[order(myDF$Date)]
amountPerDate = aggregate(data=myDF, Amount ~ Date, sum)
amountPerDate

产生这样的输出:

Date        Amount
01/02/2018  220
01/03/2018  300
01/04/2018  340
01/12/2018  100
01/14/2018  100

所以用户可以看到每个日期的总金额,日期顺序正确。几个月来,我一直在用常规的 R 脚本做这样的事情,但以前从未尝试过闪亮的。

因此,要将数据上传到闪亮,我正在使用以下代码:

shinyServer(function(input, output){
 output$contents <- renderTable({
  inFile <- input$file1
  if(is.null(inFile))
   return(NULL)
  userData = read.csv(inFile$datapath, sep=",")

  #here I run chunks of code to clean the data

  #assign data frame to global environment
  assign("userData", userData, envir = .GlobalEnv)

  #display data table in app
  userData
})

所以现在用户可以查看数据但不能对它做任何事情。

全局环境中的数据框将每个变量都作为类因子。我认为将变量强制转换为适当的类很容易(“ID”和“Amount”为数字,“Name”为字符,“Date”为日期,但我做不到。接下来我尝试让应用程序做的是在第一行显示日期。我用这个代码试过:

output$text <- renderText({
 userData$Date  = as.Date(as.character(userData$Date), format = "%m/%d/%Y")
 userData[1,2]
})

但应用程序中的输出是 17533,而不是我预期的 01/12/2018。

由于某些奇怪的原因,以下代码将产生 01/12/2018 的输出:

output$text <- renderText({
 userData$Date = as.character(userData$Date)
 userData[1,2]
})

但我需要日期是类 DATE,而不是类字符。

如果无法将变量强制转换为适当的类,我的整个应用程序就毫无用处。请帮忙。

4

1 回答 1

0

不要在 Shiny 中使用 assign,这是不好的做法,也不允许任何反应。相反,使用响应式存储您的输入数据。

关于意外的打印输出,这可能与日期的存储方式有关。如果您在 renderText 中输出 Date 对象,它显然会将其解析为整数值并将其转换为字符。为防止这种情况,请先将其解析为自己的角色。

这是一个工作示例:

library(shiny)
library(data.table)
server <- function(input, output, session) {

  filedata <- reactive({
    infile <- input$file1
    if (is.null(infile)) {
      return(NULL)
    }
    df <- fread(infile$datapath)
    return(df)
  })

  output$my_table <- renderDataTable({
    if(is.null(filedata()))
    {
      return(NULL)
    }
    else
    {
      myDF <- filedata() # read the uploaded data from reactive
      myDF$Date <- as.Date(myDF$Date, format="%m/%d/%Y") # Change format!
      sortedByDate = myDF[order(myDF$Date)]
      amountPerDate = aggregate(data=myDF, Amount ~ Date, sum)
      print('done')
      return(amountPerDate)
    }
  })

  output$my_text <- renderText({
    if(is.null(filedata()))
    {
      return(NULL)
    }
    else
    {
      as.character(as.Date(filedata()$Date, format="%m/%d/%Y"))[1]
    }
  })
}


ui <- fluidPage(
  fileInput("file1", "Choose CSV File",
            accept = c(
              "text/csv",
              "text/comma-separated-values,text/plain",
              ".csv")
  ),
  dataTableOutput('my_table'),
  textOutput('my_text')
)

shinyApp(ui,server)

希望这可以帮助!

于 2018-01-13T11:20:37.387 回答