私は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)
これは私のコードです。私の実際のデータは、length(ll[i])
3 ~ 300 の 9,000 要素のリストと、行数が 15,000 の data.frame で構成されています。100 万回の順列を実行したいのですが、256 GB の RAM サーバーで実行しても、RAM メモリの観点からこれは不可能です。だから、私の考えは、ジョブをチャンクに分割し、別々に保存することですperm.pval
オブジェクトを後で結合します。ただし、毎回同じ値を選択することを避けるために、サンプリング手順を個別に行う必要があります。10000 個の順列の 100 個のジョブを手動で実行できますが、使用できる RAM の最大レベルに達しないように 10 個のチャンクで実行します。それを自動的に行う方法、つまり、コマンド ラインで多数の R ジョブを実行するが、同時にではなく実行する方法、つまり、10 回実行して終了を待ってから、さらに 10 回実行する方法があるかどうか疑問に思います (私は提案しています)。これにより、RAM の使用を避けることができます)。
手がかりは大歓迎です