提高Rshiny的计算速度
我正在尝试开发一个基本的R闪亮应用程序,但在处理速度方面遇到了问题。程序如下,我需要读取大约500K行的csv文件->将文件分割成更小的段->计算每个段的新特征并显示结果。下面是我的提高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
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中)你的功能,但可能这是调试代码的一部分。感谢你的解释,我尝试了将函数转换为反应式。现在它正按预期工作。