在编写文件时,我很难并行化R以优化函数调用的速度。功能很简单,但它创建的文件非常庞大,并且需要花费不合理的时间。我一直在使用profvis来可视化时间的去向,并且看起来嫌疑人在函数结尾的cat语句中,以及在写入输出文件时的捕获步骤中。我在下面包含了一个简化的,小的,可重现的示例脚本,但实际文件很大,我在超级计算集群上运行它们。并行运行脚本并没有给我任何速度提升,但是我对如何构造foreach语句感到不知所措,以便它实际上并行捕获函数的每次迭代。将foreach放入函数本身会给我带来订单问题(而不是标题,基本削减,标题,基数对等,它会随机附加它们 - 但它们碰巧已经从它们运行的任何核心中脱落)并将其放入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}
答案 0 :(得分:0)
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)
新代码:
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)
在loop
的每个foreach
中,按行迭代my.df
。然后%do%
以下rbind
Header()
和substring...
,然后转为data.frame
。最后,.combine
输出rbind
。这将生成单列数据帧。使用write_tsv...
写入输出文件。
输出:
V1
1 1054:1658
2 GACCACTCC
3 1578:1988
4 CAAACGGCT
5 1604:1065
<强> ------ --------并行强>
要进行并行化,只需将%do%
替换为%dopar%
即可。根据您拥有的条目数量,%do%
实际上可能更快。