2012-11-14 6 views
1

루프에 맞는 nls의 잔여 물의 ​​부트 스트랩을하고 싶습니다. 나는 nlsBoot을 사용하고 계산 시간을 줄이기 위해 병렬로 (현재 Windows 7 시스템에서)하고 싶습니다.nlsBoot 및 foreach % dopar % : 범위 지정 문제

#function for fitting 
Falge2000 <- function(GP2000,alpha,PAR) { 
    (GP2000*alpha*PAR)/(GP2000+alpha*PAR-GP2000/2000*PAR) 
} 

#some data 
PAR <- 10:1600 
GPP <- Falge2000(-450,-0.73,PAR) + rnorm(length(PAR),sd=0.0001) 
df1 <- data.frame(PAR,GPP) 

#nls fit 
mod <- nls(GPP~Falge2000(GP2000,alpha,PAR),start=list(GP2000=-450,alpha=-0.73),data=df1, upper=c(0,0),algorithm="port") 

#bootstrap of residuals 
library(nlstools) 
summary(nlsBoot(mod,niter=5)) 
#works 

#now do it several times 
#and in parallel 
library(foreach) 
library(doParallel) 

cl <- makeCluster(1) 
registerDoParallel(cl) 

ttt <- foreach(1:5, .packages='nlstools',.export="df1") %dopar% { 
    res <- nlsBoot(mod,niter=5) 
    summary(res) 

} 
#Error in { : 
#task 1 failed - "Procedure aborted: the fit only converged in 1 % during bootstrapping" 

stopCluster(cl) 

나는 환경과이 문제를 의심하고 nlsBoot의 코드를보고 후 문제가 lapply 전화에 익명 함수의 사용에서 발생하는 것 : 여기 내 문제를 재현하는 코드이며,

l1 <- lapply(1:niter, function(i) { 
    data2[, var1] <- fitted1 + sample(scale(resid1, scale = FALSE), 
     replace = TRUE) 
    nls2 <- try(update(nls, start = as.list(coef(nls)), data = data2), 
     silent = TRUE) 
    if (inherits(nls2, "nls")) 
     return(list(coef = coef(nls2), rse = summary(nls2)$sigma)) 
}) 
if (sum(sapply(l1, is.null)) > niter/2) 
    stop(paste("Procedure aborted: the fit only converged in", 
     round(sum(sapply(l1, is.null))/niter), "% during bootstrapping")) 

병렬 루프에서 nlsBoot을 사용할 방법이 있습니까? 아니면 함수를 수정해야합니까? 모든 확인을 작동처럼 (내가 lapply 대신 for 루프를 사용을 시도 할 수 있습니다.)

+0

'mod' 객체를 (% 자동으로 내보내는 대신)'% dopar %'루프 안에 만들려고 했습니까? – BenBarnes

답변

1

%dopar% 루프에 mod 객체의 생성을 이동하여, 그것은 보인다. 또한 df1 개체를 자동으로 내 보내므로 .export 인수를 제거 할 수 있습니다.

ttt <- foreach(1:5, .packages='nlstools') %dopar% { 
    mod <- nls(GPP~Falge2000(GP2000,alpha,PAR),start=list(GP2000=-450,alpha=-0.73),data=df1, upper=c(0,0),algorithm="port") 
    res <- nlsBoot(mod,niter=5) 
    capture.output(summary(res)) 

} 

그러나 반환 할 항목을 찾아야 할 수도 있습니다. capture.output을 사용하면 summary(res)이 (가) NULL만을 반환하는 것으로 보였으므로 문제가 없는지 확인할 수있었습니다.

+0

감사합니다. 이 간단한 예제와 함께 작동하지만 내 실제 문제와 함께 작동하지 않습니다. 나는 함수에서'nlsBoot'의 코드를 제거하고 결국 계수를 반환하는 방식으로 약간 단순화했습니다. – Roland