【问题标题】:Can readLines be executed in parallel within R可以在R中并行执行readLines吗
【发布时间】:2013-03-11 21:45:41
【问题描述】:

是否可以在单个多核机器上与 R 并行迭代单个文本文件?就上下文而言,文本文件介于 250-400MB 的 JSON 输出之间。

编辑:

这是我一直在玩的一些代码示例。令我惊讶的是,并行处理并没有获胜——只是基本的 lapply——但这可能是由于我的用户错误。另外,当我尝试读取大量大文件时,我的机器卡住了。

## test on first 100 rows of 1 twitter file
library(rjson)
library(parallel)
library(foreach)
library(plyr)
N = 100
library(rbenchmark)
mc.cores <- detectCores()
benchmark(lapply(readLines(FILE, n=N, warn=FALSE), fromJSON),
          llply(readLines(FILE, n=N, warn=FALSE), fromJSON),
          mclapply(readLines(FILE, n=N, warn=FALSE), fromJSON),
          mclapply(readLines(FILE, n=N, warn=FALSE), fromJSON, 
                   mc.cores=mc.cores),
          foreach(x=readLines(FILE, n=N, warn=FALSE)) %do% fromJSON(x),
          replications=100)

这是第二个代码示例

parseData <- function(x) {
  x <- tryCatch(fromJSON(x), 
                error=function(e) return(list())
                )
  ## need to do a test to see if valid data, if so ,save out the files
  if (!is.null(x$id_str)) {
    x$created_at <- strptime(x$created_at,"%a %b %e %H:%M:%S %z %Y")
    fname <- paste("rdata/",
                   format(x$created_at, "%m"),
                   format(x$created_at, "%d"),
                   format(x$created_at, "%Y"),
                   "_",
                   x$id_str,
                   sep="")
    saveRDS(x, fname)
    rm(x, fname)
    gc(verbose=FALSE)
  }
}

t3 <- system.time(lapply(readLines(FILES[1], n=-1, warn=FALSE), parseData))

【问题讨论】:

  • 是读取JSON文件的问题还是解析JSON文件的问题?
  • 两者都不是。当我尝试使用简单的 for 循环时,我的机器最终会死机。我尝试对每个 JSON 条目运行一个函数,保存单独的 rds 文件以重新读入,等等。对于每个选项,我也意识到内存使用情况,并在可能的情况下尝试优化和清理。有些想法很糟糕,但最后,我想找出仅使用 Base R 来“分析”更大数据集的方法,而忽略了目前存在更好解决方案的事实。
  • 一个可重复的示例将使我们更容易提供反馈。

标签: r parallel-processing


【解决方案1】:

答案取决于问题实际是什么:并行读取文件,或并行处理文件。

并行读取

您可以将 JSON 文件拆分为多个输入文件并并行读取它们,例如将plyr 函数与并行后端结合使用:

result = ldply(list.files(pattern = ".json"), readJSON, .parallel = TRUE)

注册后端可能可以使用parallel 包完成,该包现已集成在基本 R 中。或者您可以使用doSNOW 包,详情请参阅this post on my blog

并行处理

在这种情况下,最好的办法是将整个数据集读入一个字符向量,拆分数据,然后使用并行后端结合例如plyr 函数。

【讨论】:

  • 不错的主意。如果您正在寻找一种方法来分割文件,请查看 UNIX split 命令。
  • @JeffAllen 有趣。并没有真正考虑过使用命令提前对数据进行预处理。无论如何都不是命令行专家,但我越是摸索,我就会发现一些命令有多么强大。
【解决方案2】:

由于非并行文件系统 IO 的性质,可能不适用于 readLines()。当然,如果您使用并行 NFS 或类似 HDFS 的东西,则此限制将不适用。但假设您使用的是“标准”架构,并行化您的 readLine() 调用将不可行。

您最好的选择可能是读入整个文件,因为

【讨论】:

  • +1,但是通过一些工作,您可能可以通过将行号分配给他们需要从给定文件连接中读取的每个工作人员来获得并行 readLines
  • @PaulHiemstra 你能举例说明在最简单的情况下如何做到这一点吗? :)
  • @AnthonyDamico 我现在没有时间,但我认为这不是微不足道的,而且很可能行不通。
猜你喜欢
  • 2011-11-05
  • 1970-01-01
  • 1970-01-01
  • 2020-02-04
  • 1970-01-01
  • 2014-03-09
  • 2011-12-19
  • 2020-06-15
  • 2023-03-31
相关资源
最近更新 更多