我正在使用Windows 8,并希望获得不需要Linux的解决方案。
我的实际问题要复杂得多,但如果这可行,那么我的问题就会解决。由于工作被分成不同的核心,所有的"之前的"计算在每次迭代中都不可用。这是我的尝试:
library(snow)
library(doSNOW)
library(foreach)
cl <- makeCluster(3, type="SOCK")
registerDoSNOW(cl)
avg_x <- 0
foo <- foreach(i=1:10, .combine='rbind') %dopar% {
x <- rnorm(1, 0, 1)
if (i == 1) avg_x <- x
if (i > 1) avg_x <- (avg_x*(i-1) + x) / i
return(list(index=i,
x=x,
avg_x=avg_x))
}
stopCluster(cl)
foo <- as.data.frame(foo)
foo$real_avg <- cumsum(foo$x)/(1:10)
这是输出:
> foo
index x avg_x real_avg
result.1 1 0.5794659 0.5794659 0.57946591
result.2 2 -0.425142 -0.212571 0.07716198
result.3 3 -0.7871111 -0.2623704 -0.21092906
result.4 4 0.7277492 0.6165367 0.02374051
result.5 5 -1.236796 -0.4174159 -0.22836676
result.6 6 -0.4746637 0.43467 -0.26941625
result.7 7 1.121336 -0.1975943 -0.07073741
result.8 8 0.007783448 0.3813092 -0.06092231
result.9 9 -1.218424 -0.3110198 -0.18953361
result.10 10 0.3948681 0.3826651 -0.13109344
如果无法计算每次迭代的运行平均值,是否有可能在每3次迭代后以某种方式计算它?
更新: 我有一个关于如何做到这一点的想法,我认为它会起作用,但我似乎无法正确编程。我们的想法是更新foreach中的data.frame。 4名工人中的3名将生成随机数,另一名将使用之前的迭代计算运行平均值。我尝试更新data.frame时遇到错误。
library(snow)
library(doSNOW)
library(foreach)
cl <- makeCluster(4, type="SOCK")
registerDoSNOW(cl)
f <- data.frame(x=rep(0,13),
ind=rep(0,13),
runAvg=rep(0,13))
foreach(i=icount(13), .export='f') %dopar% {
if (i == 1) return
if ((i-1)%%4 != 0) {
#cores 2, 3, 4 just get populated with the random numbers
f[i,] <- c(rnorm(1, 0, 1), i, 0)
}
if ((i-1)%%4 == 0){
#core 1 only calculates the running average
f[i,] <- (f[i-4,3]*(i - 4 - (i+3)/4)) + (f[i-3,1] + f[i-2,1] + f[i-1,1])/(i - (i+3/4))
}
}
stopCluster(cl)
f
最后我收到一个错误,data.frame f根本没有改变。这是我得到的错误:
Error in { : task 1 failed - "replacement has 0 items, need 3"
In addition: Warning message:
In e$fun(obj, substitute(ex), parent.frame(), e$data) :
already exporting variable(s): f