如何加速将数据加载到R? 问题是:
数据集需要6-12个小时才能加载到R中。更大的数据集即将出现,而且 我目前的导入过程显然还没有准备好。一旦一切都在数据中 框架的大小不是问题;大多数操作只需几秒钟,因此我的 硬件可能不是问题所在 注意:这个问题不是类似问题的重复,因为我已经实现了来自相关线程的大部分建议,例如specify ColClass 数据: 选项卡分隔文本文件中的行如下所示:如何加速将数据加载到R? 问题是:,r,R,数据集需要6-12个小时才能加载到R中。更大的数据集即将出现,而且 我目前的导入过程显然还没有准备好。一旦一切都在数据中 框架的大小不是问题;大多数操作只需几秒钟,因此我的 硬件可能不是问题所在 注意:这个问题不是类似问题的重复,因为我已经实现了来自相关线程的大部分建议,例如specify ColClass 数据: 选项卡分隔文本文件中的行如下所示: 20 -0.5 1 2 1 1 19 0 119 30 exp(-31.3778) 加载数据: 我定义了两个函数
20 -0.5 1 2 1 1 19 0 119 30 exp(-31.3778)
加载数据:
我定义了两个函数,它们一起循环文件以加载
将数据存储到单个数据帧中,然后将其另存为blob。这就是
需要几个小时。可以预见,随着进程的进行,进程会减慢并使用更多内存;top表示R使用了超过95%的CPU,并且(更重要的是?)在数据文件运行到一半时,使用了超过1.5 GB的实际内存
# get numeric log from character data
extract_log <- function(x) {
expr <- "exp\\((.*)\\)"
substring <- sub(expr, "\\1", x)
log <- as.numeric(substring)
return(log)
# reads .dat files into data frames
read_dat <- function(x, colClasses = c(rep("numeric", 10), "character")) {
df <- read.table(x, header = TRUE, sep = "\t", comment.char = "",
colClasses = colClasses)
df <- cbind(df, log_likelihood = sapply(df$likelihood, extract_log))
df$likelihood <- exp(df$log_likelihood)
# drop nat. log col, add log10 column shifting data to max = 0
df <- transform(df,
rlog_likelihood = log10(likelihood) - max(log10(likelihood)))
return(df)
}
# creates a single data frame from many .dat files
df_blob <- function(path = getwd(), filepattern = "*.dat$",
outfile = 'df_blob.r', ...) {
files <- list.files(path = path, pattern = filepattern, full.names = TRUE)
progress_bar <- {
txtProgressBar(min = 0, max = length(files),
title = "Progress",
style = 3)
}
df <- read_dat(files[1])
setTxtProgressBar(progress_bar, 1)
for (f in 2:length(files)) {
df <- rbind(df, read_dat(files[f]))
setTxtProgressBar(progress_bar, f)
}
close(progress_bar)
save(df, file = outfile)
}
#从字符数据获取数字日志
expndtw-1\u-log基本的一个大问题是read.table
不是很快。您可以通过设置colClasses
和nrows
对其进行调整,但在一天结束时,如果数据加载需要12小时,则需要使用不同的技术
一种更快的方法是将数据导入数据库,然后将其读入R。JD Long演示了一种使用sqlite
数据库和sqldf
包的方法。MonetDB和MonetDB.R
包是为快速完成这类工作而设计的,值得研究
正如Justin和Joran都发现的那样,使用rbind(df,read_dat(files[f])
在循环中增量增长数据帧是一个巨大的瓶颈。如果完整的数据集适合RAM,那么更好的方法是使用do.call(files,read.table)
。(如果没有,请使用上述方法将所有内容插入数据库,并将所需内容拉入R)。步骤df同样,我会认真调查在read_dat
中的每个单独部分上进行所有这些转换的成本,不要一次使用像data.table
这样的东西。您是否对一组(稍小的)数据运行profile
,以查看哪些操作是最重要的?您应该尝试使用require(data.table);rbindlist(lappy(files,fread))
读取文件,然后遵循@joran的建议。这篇文章很有意义:。我认为这些都是很好的建议,但我不确定我是否同意他的根本问题真的是read.table
。我认为他目前的瓶颈是(按降序):通过rbind
增加df,调用transform
7000次(即重复执行所有转换而不是一次),最后触摸他的磁盘7000次。如果使用read.table的一个好的解决方案至少在使用上非常快,我不会感到惊讶。我将尝试两种方法,即加快read.table的建议和Richie从数据库中读取的建议。频繁的磁盘访问可能不是一个大问题,因为我正在使用一个快速的新SSD。我错过了关于在循环中增长df
的一行。好的。