【发布时间】:2018-03-27 06:06:09
【问题描述】:
我正在尝试开发一个基本的 R 闪亮应用,但面临处理速度的问题。过程如下,我需要读取大约 500K 行的 csv 文件 -> 将文件拆分为更小的段 -> 计算每个段的新特征并显示结果。下面是我的UI.R 和Server.RUI.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)
}
)
})
如果我读取大约 2k 行的 csv 文件,该应用程序可以正常工作,但如果我读取的数据集超过 2k,则该应用程序无法正常工作,它既不会给出任何错误,也不会崩溃。微调器继续旋转,但无法显示结果。此外,在常规 R script 中使用相同的逻辑时,可以很好地处理超过 500k 的大型数据集,而我正在计算 22 的新功能。
目前,我正在使用8gb RAMi5 Processor的系统。有没有办法提高计算速度,当在我的任务管理器中检查时Rstudio 只使用大约47% - 52% 的内存,除了R studio 之外我没有其他进程在运行
编辑:可以使用以下代码创建示例数据,drive <- as.data.frame(sample(1:50, 500000, replace = T))
【问题讨论】:
-
请不要提供指向谷歌驱动器数据的链接;当(不是如果)链接过时,这个问题将完全无法重现。相反,我建议您提供一个完全独立的可重现问题,包括问题中的代表性数据(可能使用
dput(head(x,n=20))或类似的)。 -
@r2evans 好的,我将删除链接并提供示例数据。
-
read.csv是出了名的慢。尝试fread,对于初学者 -
@MichaelChirico 感谢您的建议,我尝试使用
fread,但没有成功,问题不在于读取文件,而在于计算features。 -
您可能需要分析您的代码以准确了解时间花在哪里并专注于该部分。从您的代码看来,您计算了两次(在 renderDataTable 和 write.csv 中)您的功能,但它可能是您的调试代码的一部分