r - 如何加快将数据加载到 R 中的速度?

标签 r

问题:

数据集需要 6-12 个小时才能加载到 R 中。更大的数据集即将到来,并且 我当前的导入过程显然还没有为他们准备好。一旦全部在数据中 框架大小不是问题;大多数操作只需要几秒钟,所以我的 硬件可能不是问题。

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

数据:

制表符分隔的文本文件中的行如下所示:

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)
}

解决方案

所需时间已从数小时减少到数秒。

  1. 使用 shell 脚本连接数据文件(所需时间约 12 秒)
  2. 使用 sqldf 加载连接文件(所需时间约 6 秒)

用 shell 脚本连接数据文件(所需时间 ~12 秒) 然后完全按照 JD Long's answer to a related question 中的描述使用 sqldf() 加载它们正如他在 blog post 中所描述的那样.

经验教训

Justin 和 Joran 的评论显着提高了我的 read.table() 方法的效率,对于较小的数据集,该方法应该可以正常工作。特别是 Justin 的建议,用 do.call(rbind, lapply(files, read_dat)) 替换 rbind(df, read_dat(files[f])) 对文件的循环> 将执行时间缩短约 2/3。其他建议的改进较为温和,但仍然值得。

最佳答案

基础 您遇到的一个大问题是read.table 不是很快。您可以通过设置 colClassesnrows 对其进行调整,但归根结底,如果您的数据需要 12 小时才能加载,则您需要使用不同的技术。

更快的方法是将数据导入数据库,然后将其读入 R。JD Long 演示了一种使用 sqlite 数据库和 sqldfin this answer 的方法。 MonetDB 和 MonetDB.R 包专为快速执行此类操作而设计,值得研究。


正如 Justin 和 Joran 都发现的那样,使用 rbind(df, read_dat(files[f])) 在循环中增量增长数据帧是一个巨大的瓶颈。如果完整数据集适合 RAM,更好的方法是使用 do.call(files, read.table)。 (如果没有,请使用上述方法将所有内容删除到数据库中,然后将您需要的内容拉入 R。)

关于r - 如何加快将数据加载到 R 中的速度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19863467/

相关文章:

r - 是否可以在 highcharter map 中包含 map 线?

r - 在 R 中生成列表的所有不同排列

r - 如何 reshape 数据以在 R 中创建多变量箱线图的各个方面

r - 将向量打印到具有预定义列数的文件,无需回收

r - 将 R 中的两个 data.frames 与不同的行组合

R数据.表: In-memory left join multiple columns from left and right side

r - 如何为 R 包中的 cpp 函数编写测试?

r - 分解 R 包中的 disag_model() 函数存在问题

R 逻辑运算符 - 何时使用感叹号与破折号(!x 和 -x)?

r - 如何在shiny app中播放本地视频?(Windows)