我有一个 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 之间的元素和行数为 15,000 的 data.frame。我想运行一百万个排列,但是即使我在 256 GB RAM 服务器上运行它,就 RAM 内存而言这是不可能的。所以,我的想法是将工作分成几块并存储不同的perm.pval
对象,然后将它们组合起来。但是,我需要单独进行采样过程以避免每次都选择相同的值。我可以手动运行 100 个 10000 个排列的作业,但以 10 个为一组,无法达到我可以使用的最大 RAM 水平。我想知道是否有一种方法可以自动完成,即在命令行中运行大量 R 作业但不是同时运行,即运行 10 等待完成,然后再运行 10(我建议这是为了避免使用 RAM)。
欢迎任何线索