【问题标题】:How to use a multiply imputed data set (mids) object in a foreach loop in R?如何在 R 的 foreach 循环中使用多重插补数据集(mids)对象?
【发布时间】:2020-10-21 00:01:31
【问题描述】:

我正在尝试使用并行计算来计算最小绝对偏差回归参数的百分位引导 95% 置信区间,如article 中所述。但是,我没有使用单个数据框,而是使用多重插补数据集 (mids) 对象,通过 mice 包获得用于多重插补。这就是问题所在。

我想在 foreach 循环中使用mids(或多重插补数据集列表)对象,执行引导,并汇集结果。通过将mids 对象转换为列表,然后使用该列表中的一个元素,我设法仅基于一个数据集获得结果。尽管如此,我还是想一次性使用所有数据集。

一个可重现的例子:

library(foreach)
library(doParallel)
cores_2_use <- detectCores() - 1

cl <- makeCluster(cores_2_use)
clusterSetRNGStream(cl, 9956)
registerDoParallel(cl)

library(mice)
imp_merged <-
  foreach(no = 1:cores_2_use, 
          .combine = ibind, 
          .export = "nhanes",
          .packages = "mice") %dopar%
  {
    mice(nhanes, m = 30, printFlag = FALSE)
  }
stopCluster(cl)

这是我尝试过的:

library(quantreg)
library(mitml)
library(miceadds)
library(splines)

cl <- makeCluster(cores_2_use)
clusterSetRNGStream(cl, 9956)
registerDoParallel(cl)

boot.1 <- foreach(i = 1:100,
                  .combine = rbind,
                  .packages = c('quantreg', 'mice', 'mitml', 'splines')) %dopar% {
                    
                    longlist <- miceadds::mids2datlist(imp_merged)
                    boot_dat <- longlist[[6]][sample(1:nrow(longlist[[6]]), replace = TRUE), ]
                    ## This is now based only on the 6th element of longlist
                    ## I would like to use the whole mids/longlist object (330 data sets on my PC)
                    
                    fit1 <- rq(chl ~ ns(bmi, df = 2, B = c(21, 33)) +
                                 hyp + age, tau = 0.5,
                               data = boot_dat)
                    fit1$coef
                  }
stopCluster(cl)

boot.1.df <- as.data.frame(boot.1)
boot.1.pooled <- do.call(cbind, boot.1.df)
boot.1.ci <- apply(boot.1.pooled, 2, quantile, probs = c(0.025, 0.975))
t(boot.1.ci)

我将mids 对象转换为带有longlist &lt;- miceadds::mids2datlist(imp_merged) 的多重插补数据集列表,并通过boot_dat &lt;- longlist[[6]][sample(1:nrow(longlist[[6]]), replace = TRUE), ] 基于该列表的一个元素(即插补数据集)执行采样。我想使用整个mids 对象或longlist 的所有元素。

任何帮助将不胜感激!

【问题讨论】:

  • 这真的是并行化的问题吗?您似乎对 foreach 循环中的内容有疑问。
  • 你说得对,谢谢。我相应地编辑了帖子。
  • 当您说要使用整个 mids 对象时,您希望得到所有 30 个插补样本的合并结果,对吗? (顺便说一句,既然您设置了m = 30,那么“330 个数据集”是错字吗?)您将引导算法应用于所有 30 个插补,获得您感兴趣的统计数据的引导标准误差并使用mice::pool.scalar 来结合插补间和插补内的方差。您可能需要在合并之前转换您的统计数据(并在之后对合并的统计数据进行反向转换),请参阅Stef van Buuren's ebook
  • @benimwolfspelz 我不确定这是一个错字。只是有 11 个核心?
  • @F.Privé 我知道这个数字可能来自哪里。但这意味着 Dion 做了 330 个插补样本,考虑到experts recommend 20-100(或过去 5-10),这是一个极端数字。

标签: r loops foreach r-mice


【解决方案1】:

一种可能的方法是将数据集简单地组合成一个大数据集,然后直接从中采样。

longlist_ = longlist[[1]]
for (j in 2:length(longlist))
  {
    longlist_ = rbind(longlist_,longlist[[i]])
  }
boot_dat <- longlist_[sample(1:nrow(longlist[[6]]), replace = TRUE), ]

另一种方法是随机选择一个数据集,随机选择一行,重复几次。

boot_dat = NULL
for (j in seq(nrow(longlist[[6]])))
  {
    boot_dat = rbind(boot_dat, 
               longlist[[sample(length(longlist),1)]][sample(nrow(longlist[[1]]),1),])
  }

注意,为避免rq中奇异设计矩阵的错误,可以添加一个小噪声。

boot_dat[,'hyp'] = boot_dat[,'hyp'] + runif(nrow(boot_dat), -1e-10, 1e-10)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-28
    • 2019-02-04
    • 1970-01-01
    • 2020-10-31
    • 1970-01-01
    • 1970-01-01
    • 2016-10-27
    相关资源
    最近更新 更多