如何加速将数据加载到R? 问题是:

如何加速将数据加载到R? 问题是:,r,R,数据集需要6-12个小时才能加载到R中。更大的数据集即将出现,而且 我目前的导入过程显然还没有准备好。一旦一切都在数据中 框架的大小不是问题;大多数操作只需几秒钟,因此我的 硬件可能不是问题所在 注意:这个问题不是类似问题的重复,因为我已经实现了来自相关线程的大部分建议,例如specify ColClass 数据: 选项卡分隔文本文件中的行如下所示: 20 -0.5 1 2 1 1 19 0 119 30 exp(-31.3778) 加载数据: 我定义了两个函数

数据集需要6-12个小时才能加载到R中。更大的数据集即将出现,而且 我目前的导入过程显然还没有准备好。一旦一切都在数据中 框架的大小不是问题;大多数操作只需几秒钟,因此我的 硬件可能不是问题所在

注意:这个问题不是类似问题的重复,因为我已经实现了来自相关线程的大部分建议,例如specify ColClass

数据: 选项卡分隔文本文件中的行如下所示:

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
的一行。好的。