提高Rshiny的计算速度

提高Rshiny的计算速度,r,shiny,R,Shiny,我正在尝试开发一个基本的R闪亮应用程序,但在处理速度方面遇到了问题。程序如下,我需要读取大约500K行的csv文件->将文件分割成更小的段->计算每个段的新特征并显示结果。下面是我的UI.R和Server.R UI.R library(shiny) library(shinyBS) library(shinycssloaders) library(DT) shinyUI(fluidPage( mainPanel( #UI for choosing the file to input fil

我正在尝试开发一个基本的R闪亮应用程序,但在处理速度方面遇到了问题。程序如下,我需要读取大约500K行的csv文件->将文件分割成更小的段->计算每个段的新特征并显示结果。下面是我的
UI.R
Server.R

UI.R

library(shiny)
library(shinyBS)
library(shinycssloaders)
library(DT)


shinyUI(fluidPage( 
mainPanel(
#UI for choosing the file to input
fileInput("file1", label = (" Choose Drivecycle Data "),multiple = F),

#UI for showing the number of Rows in original dataset 
fluidRow(
  column(8, h4(helpText("Number of rows input dataset"))),
  column(3,verbatimTextOutput("totrows", placeholder = TRUE))),

#UI for showing the number of segments the data set had been split into
fluidRow(
  column(8, h4(helpText("Number of segmentations"))),
  column(3,verbatimTextOutput("totseg", placeholder = TRUE))),

fluidRow(
  column(8, downloadButton("subtablednld", label = 'Downloadcsv'))
),

tabsetPanel(

  #UI to show the original data set in First tab
  tabPanel("Table",icon = icon("table"),withSpinner(DT::dataTableOutput('table'), 
                                                    type = getOption("spinner.type", default = 8) )),

  #UI to show the  features of the segments of the orginal dataset in Second Tab
  tabPanel("Feature Table",icon = icon("table"),withSpinner(DT::dataTableOutput('table1'), 
                                                            type = getOption("spinner.type", default = 8) )),


),style = 'width:1000px;height"3000px'
)
)
)
Server.R

library(shiny)
library(earth)
library(tidyr)

options(shiny.maxRequestSize=300*1024^2) #increase the max upload file size 
to 30 MB
options(shiny.trace=TRUE)

# Define server logic required to draw a histogram
shinyServer(function(input, output) {

#Function to input data set using UI 
dataframe <- reactive( {

###  Create a data frame reading data file to be used by other functions..
inFile <- input$file1

data1 <- read.csv(inFile$datapath, header = TRUE)

 })

 #Display the input dataset
 observeEvent(input$file1,output$table <- renderDataTable({dataframe()}))

 #Show the number of rows in the input dataset
 observeEvent(input$file1,output$totrows<- renderText({nrow(dataframe())}))

 #Split the data set
 Splitfile <- function(){
 split(dataframe(), (seq(nrow(dataframe()))-1) %/% 200)
 }

 #Show the number of segments the data has been split into
 observeEvent(input$file1,output$totseg <-renderText({length(Splitfile())}))

  #Acceleration calculation function
  Acceleration <- function(){
  c <- lapply(1:length(Splitfile()), function(i)
  {

   acceleration <- c(0,diff(Splitfile()[[i]]$Vehicle.Speed)/2)


    })
 Splitfile <- mapply(cbind, Splitfile(), "acceleration" = c, SIMPLIFY = F)
 Splitfile
 }

 #Calculating Features 

  CaclFeatures <- function(){  
  FileFeatures <- lapply(1:length(Acceleration()), function(i){

   Velocity_mean <-round(mean(Acceleration()[[i]]$Vehicle.Speed),digits = 3)

   Variance_Velocity      <-round(var(Acceleration()[[i]]$Vehicle.Speed)*
                                    ((length(Acceleration( 
                               [[i]]$Vehicle.Speed)-1)/length(Acceleration() 
                               [[i]]$Vehicle.Speed))
                                   ,digits = 3)

      c(Velocity_mean,
        Variance_Velocity)

    })
     FileFeatures<- as.data.frame(do.call(rbind, FileFeatures))
     names(FileFeatures)[names(FileFeatures) == 'V1'] <- "Velocity_Mean"
     names(FileFeatures)[names(FileFeatures) == 'V2'] <- "Variance_Velocity"
    }

    #Display the table containing all features of all the segments
      output$table1 <- renderDataTable({
         CaclFeatures()},options = list(scrollX = TRUE))


    #Print to csv
       output$subtablednld <- downloadHandler(

         filename = function(){

              paste("dataset-", ".csv", sep = "")
           },

       content = function(file){

      write.csv(CaclFeatures(), file ,row.names = FALSE)
        }
         )

      })
库(闪亮)
图书馆(地球)
图书馆(tidyr)
选项(Shining.maxRequestSize=300*1024^2)#增加最大上载文件大小
至30 MB
选项(shinny.trace=TRUE)
#定义绘制直方图所需的服务器逻辑
shinyServer(功能(输入、输出){
#使用UI输入数据集的函数

dataframe您的整个计算似乎依赖于输入data.frame中的某些结构属性,因此我无法在合理的时间内生成一个工作示例,只需对代码进行一些小的更改

但是,您的代码评估在性能方面非常出色

Acceleration
为例。
lappy
中,调用
Splitfile()
,这是一个常规函数。假设拆分的次数约为2500次,则调用该函数2500次。操作
拆分(dataframe(),(seq(nrow(dataframe())-1)%/%200)
在我的计算机上大约需要2秒,因此您需要等待5000秒,而
Splitfiles()
的结果总是一样的。然后,在
CalcFeatures
中,您调用
Acceleration()
在每个
lappy
循环中重复四次。这使得等待时间大约为5000*2500*4=50000秒或578天

您可能对
反应式
的概念感到困惑,在这个概念中,函数调用只返回当前值,而重新评估是隐式的

所以你要么:

  • 在函数开始时调用昂贵的函数一次。

    • 使用
      文件启动
      Acceleration
      请不要提供指向google drive的数据链接;当(如果)链接过期时,此问题将完全无法生成。相反,我建议您提供一个完全独立的可复制问题,包括问题中的代表性数据(可能使用
      dput(head))(x,n=20))
      或类似)@r2evans好的,我将删除链接并提供示例数据。
      read.csv
      的速度非常慢。请尝试
      fread
      ,以获取更多信息starters@MichaelChirico感谢您的建议,我尝试了
      fread
      ,但没有成功,问题不在于读取文件,而在于计算
      功能将你的代码编译成文件,以便准确地知道时间花在了哪里,并将注意力集中在这一部分上。从你的代码来看,你似乎计算了两次(在renderDataTable和write.csv中)你的功能,但可能这是调试代码的一部分。感谢你的解释,我尝试了将函数转换为反应式。现在它正按预期工作。