在 R 中的 mclapply 中使用 "sample" 无法正常工作
Using "sample" within mclapply in R not working properly
我正在尝试 运行 每次使用数据帧的不同子集对一个函数进行多次迭代。实际上,该函数需要很长时间,所以我想使用 mclapply
将迭代拆分到多个核心。对于每次迭代,我都使用 sample
来随机 select 数据帧的一个子集,这是我编写的用于 mclapply
的函数内部。但是,输出列表中每次迭代的结果都是相同的,这表明 mclapply
并不是每次都重新 运行 宁 sample
行。这一定与我编写代码的方式有关,我哪里出错了?
这是一个可以快速 运行 的小型数据集的可重现示例。您会注意到 d.val.all
输出列表中的 10 次迭代是相同的,这不是我所追求的。
library(bipartite)
library(doBy)
library(parallel)
# create dummy data
ecto.matrix1=data.frame(replicate(10,sample(0:80,81,rep=TRUE)),Species.mix.90=c(sample(c("R","M","S","B"),81,rep=TRUE)))
# set up the function
funct.resample.d <- function(i) {
RedSites <- row.names(ecto.matrix1)[ecto.matrix1$Species.mix.90=="R"]
MountainSites <- row.names(ecto.matrix1)[ecto.matrix1$Species.mix.90=="M"]
randomSilverSites <- sample(row.names(ecto.matrix1)[ecto.matrix1$Species.mix.90=="S"],8,replace=F)
randomBlackSites <- sample(row.names(ecto.matrix1)[ecto.matrix1$Species.mix.90=="B"],8,replace=F)
resampledSites <- c(RedSites,MountainSites,randomSilverSites,randomBlackSites) # make vector of the site names
matrix=ecto.matrix1[resampledSites,] # select only those rows from the resampled row names
matrix1 = matrix[,colSums(matrix[,-c(ncol(matrix))]) > 0] # drop cols that sum to 0
matrix2=summaryBy(matrix1[,-c(ncol(matrix1))]~Species.mix.90,data=matrix1,FUN=sum)
for (col in 1:ncol(matrix2)){
colnames(matrix2)[col] <- sub(".sum", "", colnames(matrix2)[col]) # remove the sum bit from the col names
}
row.names(matrix2)<-matrix2$Species.mix.90 # make row names
matrix2=subset(matrix2, select=-c(Species.mix.90)) # drop host col
d.val <- dfun(matrix2)$dprime
}
# run mclapply
reps=c(1:10)
d.val.all <- mclapply(reps, funct.resample.d, mc.cores = 10)
如果其他人遇到类似问题,我发现问题出在 summaryBy
函数而不是 sample
。我用 aggregate
替换了 summaryBy
,随机化工作正常。
matrix2=aggregate(. ~ Species.mix.90, matrix1, sum)
我正在尝试 运行 每次使用数据帧的不同子集对一个函数进行多次迭代。实际上,该函数需要很长时间,所以我想使用 mclapply
将迭代拆分到多个核心。对于每次迭代,我都使用 sample
来随机 select 数据帧的一个子集,这是我编写的用于 mclapply
的函数内部。但是,输出列表中每次迭代的结果都是相同的,这表明 mclapply
并不是每次都重新 运行 宁 sample
行。这一定与我编写代码的方式有关,我哪里出错了?
这是一个可以快速 运行 的小型数据集的可重现示例。您会注意到 d.val.all
输出列表中的 10 次迭代是相同的,这不是我所追求的。
library(bipartite)
library(doBy)
library(parallel)
# create dummy data
ecto.matrix1=data.frame(replicate(10,sample(0:80,81,rep=TRUE)),Species.mix.90=c(sample(c("R","M","S","B"),81,rep=TRUE)))
# set up the function
funct.resample.d <- function(i) {
RedSites <- row.names(ecto.matrix1)[ecto.matrix1$Species.mix.90=="R"]
MountainSites <- row.names(ecto.matrix1)[ecto.matrix1$Species.mix.90=="M"]
randomSilverSites <- sample(row.names(ecto.matrix1)[ecto.matrix1$Species.mix.90=="S"],8,replace=F)
randomBlackSites <- sample(row.names(ecto.matrix1)[ecto.matrix1$Species.mix.90=="B"],8,replace=F)
resampledSites <- c(RedSites,MountainSites,randomSilverSites,randomBlackSites) # make vector of the site names
matrix=ecto.matrix1[resampledSites,] # select only those rows from the resampled row names
matrix1 = matrix[,colSums(matrix[,-c(ncol(matrix))]) > 0] # drop cols that sum to 0
matrix2=summaryBy(matrix1[,-c(ncol(matrix1))]~Species.mix.90,data=matrix1,FUN=sum)
for (col in 1:ncol(matrix2)){
colnames(matrix2)[col] <- sub(".sum", "", colnames(matrix2)[col]) # remove the sum bit from the col names
}
row.names(matrix2)<-matrix2$Species.mix.90 # make row names
matrix2=subset(matrix2, select=-c(Species.mix.90)) # drop host col
d.val <- dfun(matrix2)$dprime
}
# run mclapply
reps=c(1:10)
d.val.all <- mclapply(reps, funct.resample.d, mc.cores = 10)
如果其他人遇到类似问题,我发现问题出在 summaryBy
函数而不是 sample
。我用 aggregate
替换了 summaryBy
,随机化工作正常。
matrix2=aggregate(. ~ Species.mix.90, matrix1, sum)