首页 > 解决方案 > 在 R 中对复杂的嵌套 for 循环进行矢量化(在数据集的不同子集上运行模型,为每个循环设置不同的数据子集)

问题描述

这是我第一次发帖,希望我能以简洁明了的方式表达我的问题。

我正在运行一个交叉验证实验,其中涉及在数据集的一个子集上训练一个模型,然后根据数据集的其余部分对其进行验证。这是通过将数据随机分组为“折叠”然后为每个折叠运行模型来完成的。然后将其复制以产生标准错误。这是我用 R 编写的代码:

reps = 10
folds = 10
rep.Res<-list()

for(i in 1:reps){
  #i=1
  phen2<-phen
  phen2$fold<-sample(1:folds,nrow(phen),replace=T)

  fold.Res<-list()

  for(j in 1:folds){
    #j=1

    print(paste(i," ",j))

    phen3<-phen2
    phen3[which(phen3$fold==j),2]<-NA

    ETA<-list(list(X = geno_centred, model = 'BayesA'))

    model <- BGLR(y = phen3[,2], ETA = ETA, nIter = 20000, 
                  burnIn = 1500,  thin=10) 

    model.output<-data.frame(ID = phen3[which(phen2$fold == j), 1],
                             PBV = as.numeric(model$yHat[which(phen2$fold == j)]),
                             phen = phen2[which(phen2$fold == j), 2], rep = i, fold = j)


fold.Res[[j]]<-model.output


  }

  rep.Res[[i]]<-do.call(rbind,fold.Res)


}

“phen”是一个具有一列 ID 和一列值的数据框。对于每个重复,每个样本被随机分配到一个折叠。然后,对于每个折叠,折叠中的个体被赋予一个 NA 值,即从模型中排除。

该模型使用贝叶斯广义线性回归 (BGLR) 包运行。不幸的是,我真的不能给出一个可重现的例子。X 是一个由 -1、0 和 1 组成的缩放中心基因型矩阵(对于我这里的问题并不重要)。然后为每个折叠写出模型的输出,然后最后为每个复制写出。

我的问题是,是否可以对这些循环进行矢量化?使用 10 次折叠和 10 次重复意味着模型运行 100 次,每次 20 000 次 MCMC 迭代。这会导致系统在完成一半之前显着减慢。我知道在 tidyverse 套件中使用基本的 R 或包有很多可能的方法,但是对于如此复杂的循环,我真的有点迷失了。我可以想象我会尝试将至少一个循环写入包含另一个循环的函数中,但我什至不确定这将如何工作......

再次,第一次发布,所以如果我需要在我的问题中添加任何内容,请告诉我!谢谢!

标签: rfor-loopvectorizationnested-loopsbayesian

解决方案


推荐阅读