如何并行R脚本或在块上运行它

时间:2013-07-11 16:48:13

标签: r command-line parallel-processing

我有一个data.frame和一个列表。我的真实数据非常庞大,所以这里的例子是我当前数据的简化。

>df

  A mac pval  P1  P2  P3  P4  P5  P6
1 a   1  0.1 0.1 0.1 0.4 0.2 0.1 0.4
2 b   1  0.2 0.1 0.4 0.2 0.1 0.2 0.2
3 c   1  0.4 0.4 0.1 0.2 0.1 0.1 0.4
4 d   2  0.1 0.1 0.7 0.5 0.1 0.7 0.1
5 e   2  0.5 0.7 0.5 0.1 0.7 0.1 0.5
6 f   2  0.7 0.5 0.5 0.7 0.1 0.7 0.1
7 g   3  0.1 0.1 0.1 0.2 0.2 0.2 0.5
8 h   3  0.2 0.2 0.1 0.5 0.2 0.2 0.5
9 i   3  0.5 0.1 0.2 0.1 0.1 0.5 0.2 

ll <- list(data.frame(AA=c("a","b","c","d")), 
             data.frame(BB=c("e","f")), 
             data.frame(CC=c("a","b","i")), 
             data.frame(DD=c("d","e","f","g")))

感谢@RicardoSaporta和其他人,我写了以下代码:

#load libraries
library(plyr)
library(data.table)

#Create a list of `df` according to `mac` value
split.mac = split(df, df$mac)
mac.pval = lapply(split.mac, '[[', 3)
df.order <- df[order(df$mac),]

#Create a list of permuted pvals using elements in list `mac.pval` 
l3 <- list()
ll1 <- length(mac.pval)
length(l3) <- ll1
set.seed(4)
for (i in 1:ll1){
   vec1 <- mac.pval[[i]]
   jl <- 1;jr<-1;
    while (length(vec1) < 4){
       if(i==1 || i-jl==0) {
          vec1 <- c(vec1, mac.pval[[i+jr]])
          jr <- jr+1
        } else if (i==ll1 || jr+i==ll1 ){
           vec1 <- c(vec1, mac.pval[[i-jl]])
           jl <- jl+1
 }else {
            vec1 <- c(vec1, mac.pval[[i-jl]], mac.pval[[i+jr]])
        jl <- jl+1
        jr <- jr+1
          } 
  } 
    l3[[i]] <- vec1  
}


#Put same names in both lists
names(l3) <- names(mac.pval)

#Create the permutations based on `l3` and add as columns to the data.frame mac.order
mac.perm <- cbind(df.order, t(sapply(df.order$mac, function(i, l)          sample(l[[as.character(i)]], 10000, replace=T), l = l3)))

#Change to data.table to speed up the calculations and keep the used RAM memory low
mac.perm.dt <- data.table(mac.perm, key='gene')

p.col.names <- paste0("P", 1:6)
nombres = c("gene", "mac", "pval", p.col.names)
names(mac.perm.dt) <- nombres
pval <- "pval"

Fisher.test <- function(p) {
    Xsq <- -2*sum(log(p), na.rm=TRUE)
    p.val <- 1-pchisq(Xsq, df = 2*sum(!is.na(p)))
    return(p.val)
 }


#Apply the function `Fisher.test` to pval and permuted columns in mac.order that corresponds to elements in the list ll
results.rand <- lapply(df.split, function(ll) mac.perm.dt[.(ll)][, lapply(.SD, Fisher.test), .SDcols=p.col.names] )
results.real <- lapply(df.split, function(ll) mac.perm.dt[.(ll)][, lapply(.SD, Fisher.test), .SDcols=pval] )

#Calculate the permuted p-values, how many times the results in results.real are higher or equal to the elements of list L2

#Transform results.real into a list and results.rand into a matrix to speed-up calculations

L1 <- as.vector(unlist(results.real))

L2 <- as.matrix(rbindlist(results.rand))

perm.pval <- (rowSums(L1 >= L2) + 1) / (ncol(L2)+1)

names(perm.pval) <- names(results.rand)

这是我的代码。我的真实数据包含9,000个元素的列表,其中length(ll[i])介于3和300之间,data.frame的行数为15,000。我想运行一百万个排列,但就RAM内存而言,这是不可能的,即使我在256 GB RAM服务器上运行它也是如此。所以,我的想法是将作业分成块并存储不同的perm.pval对象,然后将它们组合起来。但是,我需要单独进行采样程序,以避免每次都选择相同的值。我可以手动运行100个10000个排列的作业但是在10个块中没有达到我可以使用的最大RAM水平。我想知道是否有办法自动完成,即在命令行中运行大量R作业但不能同时运行,即运行10等待完成然后再运行10(我建议这样可以避免使用RAM)。

欢迎提供任何线索

0 个答案:

没有答案