在函数定义中使用foreach与使用foreach写入文件

在函数定义中使用foreach与使用foreach写入文件,r,foreach,parallel-processing,doparallel,R,Foreach,Parallel Processing,Doparallel,我在并行化R以优化写入文件时函数调用的速度方面遇到了困难。该函数很简单,但它创建的文件数量庞大,而且占用的时间不合理。我一直在使用profvis来可视化时间的走向,似乎嫌疑犯出现在函数末尾的cat语句中,以及写入输出文件时的捕获步骤中。我在下面提供了一个简化的、小的、可复制的示例纸条,但实际的文件是大量的,我正在超级计算集群上运行它们。按照编写的方式并行运行scrip并不能提高速度,但我不知道如何构造foreach语句,以便它能够并行地捕获函数的每个迭代。将foreach放入函数本身会给我带来顺

我在并行化R以优化写入文件时函数调用的速度方面遇到了困难。该函数很简单,但它创建的文件数量庞大,而且占用的时间不合理。我一直在使用profvis来可视化时间的走向,似乎嫌疑犯出现在函数末尾的cat语句中,以及写入输出文件时的捕获步骤中。我在下面提供了一个简化的、小的、可复制的示例纸条,但实际的文件是大量的,我正在超级计算集群上运行它们。按照编写的方式并行运行scrip并不能提高速度,但我不知道如何构造foreach语句,以便它能够并行地捕获函数的每个迭代。将foreach放入函数本身会给我带来顺序问题(而不是header、base pares、header、base pairs等。它随机附加它们-但是它们碰巧从运行它们的哪个内核上脱落)并将其放入capture.output行,实际上似乎没有做任何事情

预期产出:

ACCTTCGAA
1321:1007
GGGTCAATA
1258:1115
GGGCCTACG
1335:1642
ATCATCGCC
1547:1735
TCTCAACGA
1518:1935
TTGTGTTCT
1352:1828
CCTTTCGGC
1403:1162
ACAATTCGC 
可复制的示例脚本:

library(doParallel)
library(foreach)


#create cluster with desired number of cores
cl <- makeCluster(20)

# Register cluster
registerDoParallel(cl)

#create example data
bps <- replicate(10,paste(sample(size = 30, x = c("A","C","G","T"), replace = TRUE), collapse = ""))
true_false <- replicate(10,paste(sample(size = 1, x = c("T","F"), replace = TRUE), collapse = ""))
my.df<- data.frame(bps, true_false) 


#create function to make unique Header
  Header = function(){
    header = c(sample(1000:2000, 1), ":", sample(1000:2000, 1))
    paste(header, collapse="")
  }


#assemble reads:
  make_file <- function(df) { 
    bps  <- NULL 
    fragment <- seq(from=1, to=(nrow(df)))
    first.9<- seq(from=1, to=9)
    for(i in 1:nrow(df)){
      header <- Header()
      fragment[i] <- df[i,1]
      first.9 <- substring(fragment,1,9)
      bps[i] <- cat(header, first.9[i], sep = "\n")
    }
    return(bps)
  }



  #regular capture
capture.output(make_file(df = my.df), file = "myfile1.txt", append = TRUE)

  #foreach capture 
foreach(x=(capture.output(make_file(df = my.df), file = "myfile2.txt", append = TRUE))) %dopar% {x}
库(双并行)
图书馆(foreach)
#创建具有所需核心数的群集

cl
foreach
已经提供了循环行为,并尝试组装输出(您可以指定)

您的数据:

bps <- replicate(10,paste(sample(size = 30, x = c("A","C","G","T"), replace = TRUE), collapse = ""))
true_false <- replicate(10,paste(sample(size = 1, x = c("T","F"), replace = TRUE), collapse = ""))
my.df<- data.frame(bps, true_false) 
----并行化-----


要并行化,只需将
%do%
替换为
%dopar%
。根据您有多少条记录,
%do%
实际上可能会更快。

谢谢@Chi-Pak,我花了一段时间才使用实际的(更复杂的)函数,但它似乎是在小测试集上运行的——我似乎遇到了内存问题,在集群上的实际数据上运行脚本。当遇到内存问题时,您可以:A)立即将每一行写入文件(即,不要组装成大的R结构)或B)将输入文件分成小批量。如果你想得到更具体的帮助,你需要发布一个新的问题。嗨@ USS817816如果我的回答有助于你的问题,请考虑把它作为答案,点击左边的检查标记。它让社区知道它起了作用,您的问题已经解决。
library(readr)
library(iterators)
library(foreach)

newfile <- foreach(i=iter(my.df,by="row"), .combine="rbind") %do% { as.data.frame(rbind(Header(), substring(i$bps,1,9))) }
write_tsv(newfile, "C:/temp/temp.txt", append=F, col_names=F)
          V1
1  1054:1658
2  GACCACTCC
3  1578:1988
4  CAAACGGCT
5  1604:1065