嵌套的 foreach 和 dopar - 引导数据框的每一行
Nested foreach and dopar - bootstrapping each row of data frame
我有类似于此的数据框:
maindata <- data.frame(cbind(num=c(79,61,62,57),
denom=c(162356,170189,164634,162006),
group=c(1,2,3,4)))
我的意图是 select 每行,执行 bootstrap 重采样,找到 95% 置信区间的分位数,并将 CI 输出到具有 2 列和相同行数的数据框原始数据框。这个带有嵌套 foreach 和 %do% 的函数工作得很好,但是随着更多的迭代(例如 1000)和具有更多行的数据帧而变慢:
boots = function(data, boots, seed=1234){
if (!missing(seed))
set.seed(seed)
pct <- NULL
ci.pct <- list()
foreach(j=1:nrow(data)) %do% {
datast1 <- c(rep(1, data[j,]$num),
rep(0, data[j,]$denom))
foreach(i=1:boots, .combine='c') %do% {
index <- sample(1:length(datast1), size=length(datast1), replace=TRUE)
sampledata <- datast1[index]
pct[i] <- mean(sampledata)
}
ci.pct[[j]] <- cbind(quantile(pct, prob=c(0.025))*100000,
quantile(pct, prob=c(0.975))*100000)
}
ci.pcts <- do.call("rbind", ci.pct)
return(ci.pcts)
}
boots(data=maindata, boots=5, seed=1234)
我一直在尝试找出一种方法来使用 %dopar% 进行并行处理,但不太理解:
bootsd = function(data, boots, seed=1234){
if (!missing(seed))
set.seed(seed)
pct <- NULL
ci.pct <- list()
foreach(j=1:nrow(data)) %do% {
datast1 <- c(rep(1, data[j,]$num),
rep(0, data[j,]$denom))
foreach(i=1:boots, .combine='c') %dopar% {
index <- sample(1:length(datast1), size=length(datast1), replace=TRUE)
sampledata <- datast1[index]
pct[i] <- mean(sampledata)
}
ci.pct[[j]] <- cbind(quantile(pct, prob=c(0.025))*100000,
quantile(pct, prob=c(0.975))*100000)
}
ci.pcts <- do.call("rbind", ci.pct)
return(ci.pcts)
}
bootsd(data=maindata, boots=5, seed=1234)
有没有人对如何修改代码以通过正确实施 %dopar% 或其他巧妙的技巧使其更快 运行 提出建议?
我稍微重写了你的函数。我将 foreach
视为一个函数,它 returns 是循环的结果。现在它适用于 %dopar%
。唯一的问题 - 它不服从种子。每个 运行 中返回不同的结果。如果有必要,您可能必须查看 doRNG
包。
bootsd = function(data, boots, seed = 1234){
if (!missing(seed)) set.seed(seed)
ci.pct <- foreach(j = 1:nrow(data)) %do% {
datast1 <- c(rep(1, data[j, "num"]),
rep(0, data[j, "denom"]))
pct <- foreach(i = 1:boots, .combine = 'c') %dopar% {
index <- sample(1:length(datast1), size = length(datast1), replace = T)
sampledata <- datast1[index]
mean(sampledata)
}
cbind(quantile(pct, prob=c(0.025))*100000,
quantile(pct, prob=c(0.975))*100000)
}
ci.pcts <- do.call("rbind", ci.pct)
return(ci.pcts)
}
bootsd(data = maindata, boots = 5, seed = 1234)
我有类似于此的数据框:
maindata <- data.frame(cbind(num=c(79,61,62,57),
denom=c(162356,170189,164634,162006),
group=c(1,2,3,4)))
我的意图是 select 每行,执行 bootstrap 重采样,找到 95% 置信区间的分位数,并将 CI 输出到具有 2 列和相同行数的数据框原始数据框。这个带有嵌套 foreach 和 %do% 的函数工作得很好,但是随着更多的迭代(例如 1000)和具有更多行的数据帧而变慢:
boots = function(data, boots, seed=1234){
if (!missing(seed))
set.seed(seed)
pct <- NULL
ci.pct <- list()
foreach(j=1:nrow(data)) %do% {
datast1 <- c(rep(1, data[j,]$num),
rep(0, data[j,]$denom))
foreach(i=1:boots, .combine='c') %do% {
index <- sample(1:length(datast1), size=length(datast1), replace=TRUE)
sampledata <- datast1[index]
pct[i] <- mean(sampledata)
}
ci.pct[[j]] <- cbind(quantile(pct, prob=c(0.025))*100000,
quantile(pct, prob=c(0.975))*100000)
}
ci.pcts <- do.call("rbind", ci.pct)
return(ci.pcts)
}
boots(data=maindata, boots=5, seed=1234)
我一直在尝试找出一种方法来使用 %dopar% 进行并行处理,但不太理解:
bootsd = function(data, boots, seed=1234){
if (!missing(seed))
set.seed(seed)
pct <- NULL
ci.pct <- list()
foreach(j=1:nrow(data)) %do% {
datast1 <- c(rep(1, data[j,]$num),
rep(0, data[j,]$denom))
foreach(i=1:boots, .combine='c') %dopar% {
index <- sample(1:length(datast1), size=length(datast1), replace=TRUE)
sampledata <- datast1[index]
pct[i] <- mean(sampledata)
}
ci.pct[[j]] <- cbind(quantile(pct, prob=c(0.025))*100000,
quantile(pct, prob=c(0.975))*100000)
}
ci.pcts <- do.call("rbind", ci.pct)
return(ci.pcts)
}
bootsd(data=maindata, boots=5, seed=1234)
有没有人对如何修改代码以通过正确实施 %dopar% 或其他巧妙的技巧使其更快 运行 提出建议?
我稍微重写了你的函数。我将 foreach
视为一个函数,它 returns 是循环的结果。现在它适用于 %dopar%
。唯一的问题 - 它不服从种子。每个 运行 中返回不同的结果。如果有必要,您可能必须查看 doRNG
包。
bootsd = function(data, boots, seed = 1234){
if (!missing(seed)) set.seed(seed)
ci.pct <- foreach(j = 1:nrow(data)) %do% {
datast1 <- c(rep(1, data[j, "num"]),
rep(0, data[j, "denom"]))
pct <- foreach(i = 1:boots, .combine = 'c') %dopar% {
index <- sample(1:length(datast1), size = length(datast1), replace = T)
sampledata <- datast1[index]
mean(sampledata)
}
cbind(quantile(pct, prob=c(0.025))*100000,
quantile(pct, prob=c(0.975))*100000)
}
ci.pcts <- do.call("rbind", ci.pct)
return(ci.pcts)
}
bootsd(data = maindata, boots = 5, seed = 1234)