将doParallel的foreach与gamm4一起使用时出现问题

将doParallel的foreach与gamm4一起使用时出现问题,r,foreach,parallel-processing,R,Foreach,Parallel Processing,我试图使用foreach来利用并行处理来解决一个完整的子集回归问题。我试图使用gamm4软件包,使用二项式函数拟合模型的完整列表,其中响应按比例提供,权重参数提供试验次数。当使用%do%运行时,代码运行正常,但在%dopar%下失败(对于AIC和BIC,仅返回NA)。奇怪的是,如果忽略了gamm4调用的weights参数,那么代码使用%dopar%就可以正常工作,但显然这不是一个可行的解决方案。我一直在使用基于高斯分布和二项式分布的类似代码,其中响应输入为1,0(因此无需调用权重),没有任何问题

我试图使用foreach来利用并行处理来解决一个完整的子集回归问题。我试图使用gamm4软件包,使用二项式函数拟合模型的完整列表,其中响应按比例提供,权重参数提供试验次数。当使用%do%运行时,代码运行正常,但在%dopar%下失败(对于AIC和BIC,仅返回NA)。奇怪的是,如果忽略了gamm4调用的weights参数,那么代码使用%dopar%就可以正常工作,但显然这不是一个可行的解决方案。我一直在使用基于高斯分布和二项式分布的类似代码,其中响应输入为1,0(因此无需调用权重),没有任何问题。我使用的是64位windows 7,R版本为3.1.2。我已经更新了所有相关的软件包。可复制的(但不是玩具)示例:

set.seed(666)
#生成具有随机偏移效果的随机因子
random.factor=因子(排序(rep(1:10,10)))
random.effect=排序(rep(rnorm(10),10))
#生成一些随机预测变量
X1=rnorm(100)
X2=rnorm(100)
X3=rnorm(100)
X4=rep(0100)#使一个变量失败(只是为了检查“try”if语句)
#X4=rnorm(100)
X5=rnorm(100)
#根据一些预测值计算响应变量
z=1+2*X1+3*X2+2*X3^2#带偏差的线性组合
pr=1/(1+exp(-z+random.effect))#通过一个inv logit函数
y=rbinom(n=100,size=100,pr)/100#bernoulli响应变量。
#注意,反应变量是100次试验成功的比例
#我们希望将试验次数作为“权重”参数提供给gamm
#现在制作一个预测数据框架
pred.dat=数据帧(X1=X1,X2=X2,X3=X3,X4=X4,X5=X5)
pred.vars=colnames(pred.dat)
#创建一个数据帧以传递给gamm
use.dat=data.frame(random.factor=random.factor,y=y,pred.dat)
#现在设置要运行的模型
#这包括所有变量的组合,但总共只有两个变量
#任何一种型号
模型拟合试验=c(combn(1:ncol(pred.dat),1,simplify=F),
combn(1:ncol(pred.dat),2,simplify=F))
模型使用=列表(1,2,3,4,5)
n、 型号=长度(型号.配合.试验)
要求(lme4)
要求(双平行)
寄存器双并行(核心=4)
#如果我使用do运行这个函数,它工作得很好(try参数中有错误值)
#对于失败的模型返回)

out.dat它以什么方式失败?使用MacBook Pro上运行的R3.1.2和gamm4 0.2.3,我无法重现该问题。我在前两种情况下得到了相同的结果(
%do%
vs
%dopar%
)。您是在使用不同的版本还是在不同的平台上运行?对不起,我忘记添加系统信息等,请描述它失败的方式。。。。现在补充说。我在Windows7上运行R3.1.2和gamm4 0.2-3。返回的错误消息(如果我删除try语句)是:{:task 1 failed-“object”use.dat“not found”中的错误。我可以确认我遇到的问题只出现在windows系统上。
set.seed(666)

# generate a random factor with a random offset effect
random.factor=factor(sort(rep(1:10,10)))
random.effect=sort(rep(rnorm(10),10))

# generate some random predictor variables
X1 = rnorm(100)
X2 = rnorm(100)
X3 = rnorm(100)
X4 = rep(0,100)  # make it so one variable fails (just to check the "try" if statement)
#X4 = rnorm(100)
X5 = rnorm(100)

# calculate a response variable based on some of the predictors
z = 1 + 2*X1 + 3*X2 + 2*X3^2        # linear combination with a bias
pr = 1/(1+exp(-(z+random.effect)))         # pass through an inv-logit function
y = rbinom(n=100,size=100,pr)/100      # bernoulli response variable.
 # Note that the response variable is a proprotion of successes of 100 trials
 # We want to feed the number of trials as a "weights" argument to gamm

# now make a data frame of predictors
pred.dat=data.frame(X1=X1,X2=X2,X3=X3,X4=X4,X5=X5)
pred.vars=colnames(pred.dat)

# make a dataframe for passing to gamm
use.dat = data.frame(random.factor=random.factor,y=y,pred.dat)

# now set up the models to run
# this includes all combinations of variables, but only up to a total of two in
# any one model
model.fits.test=c(combn(1:ncol(pred.dat), 1,simplify = F),
             combn(1:ncol(pred.dat), 2,simplify = F))


models.use=list(1,2,3,4,5)
n.models=length(model.fits.test)

require(lme4)
require(doParallel)

registerDoParallel(cores=4)

# if I run this using do, it works fine (with error values from the try argument
# returned for models that fail)
out.dat<-foreach(l = 1:n.models,.combine=rbind,
                 .packages=c("lme4","gamm4"))%do%{
  vars.vec=model.fits.test[[l]]
  formula.l<-as.formula(paste("y~",
         paste(colnames(pred.dat)[vars.vec],collapse="+"),"+(1|random.factor)",sep=""))

  model.fit=try(glmer(formula.l,
                       data=use.dat,
                       family="binomial",
                       weights=rep(100,nrow(use.dat))))

  success<-class(model.fit)[[1]]!="try-error"

  out.vec<-c(rep(NA,2),rep(NA,ncol(pred.dat)))
  names(out.vec)<- c("AIC","BIC",colnames(pred.dat))

        out.vec[
             which(match(names(out.vec),pred.vars[vars.vec])>0)]<-1

  if(success){
        out.vec["AIC"]<-AIC(model.fit)
        out.vec["BIC"]<-BIC(model.fit)
        }
  return(out.vec)
  }

out.dat

# if I run using dopar, nothing is returned.
out.dat<-foreach(l = 1:n.models,.combine=rbind,
                 .packages=c("lme4","gamm4"))%dopar%{
  vars.vec=model.fits.test[[l]]
  formula.l<-as.formula(paste("y~",
         paste(colnames(pred.dat)[vars.vec],collapse="+"),"+(1|random.factor)",sep=""))

  model.fit=try(glmer(formula.l,
                       data=use.dat,
                       family="binomial",
                       weights=rep(100,nrow(use.dat))))

  success<-class(model.fit)[[1]]!="try-error"

  out.vec<-c(rep(NA,2),rep(NA,ncol(pred.dat)))
  names(out.vec)<- c("AIC","BIC",colnames(pred.dat))

        out.vec[
             which(match(names(out.vec),pred.vars[vars.vec])>0)]<-1

  if(success){
        out.vec["AIC"]<-AIC(model.fit)
        out.vec["BIC"]<-BIC(model.fit)
        }
  return(out.vec)
  }

out.dat



# Now run dopar without the weights argument (not really appropriate,
# but for the sake of demonstration). I get results again, but it doesn't
# really make sense to do this. Also, my real example fails unless I can supply
# weights.
out.dat<-foreach(l = 1:n.models,.combine=rbind,
                 .packages=c("lme4","gamm4"))%dopar%{
  vars.vec=model.fits.test[[l]]
  formula.l<-as.formula(paste("y~1+",
         paste("s(",colnames(pred.dat)[vars.vec],")",collapse="+"),sep=""))
  model.fit=try(gamm4(formula.l, random=~(1|random.factor),
                       data=use.dat,family="binomial"))
  success<-class(model.fit)[[1]]!="try-error"

  out.vec<-c(rep(NA,2),rep(NA,ncol(pred.dat)))
  names(out.vec)<- c("AIC","BIC",colnames(pred.dat))

        out.vec[
             which(match(names(out.vec),pred.vars[vars.vec])>0)]<-1

  if(success){
        out.vec["AIC"]<-AIC(model.fit$mer)
        out.vec["BIC"]<-BIC(model.fit$mer)
        }
  return(out.vec)
  }

out.dat