【问题标题】:apply nested foreach loops on a list在列表上应用嵌套的 foreach 循环
【发布时间】:2023-02-12 00:08:30
【问题描述】:

我正在尝试将嵌套的 foreach 循环应用于列表。使用嵌套 for 循环时,我的代码有效。但是当我尝试使用 foreach 循环时,我没有得到完整的结果(在列表中),而只是几个值。

这是我的嵌套 for 循环代码:

library(sn)
library(mnormt) 
library(mokken)
library(polycor)
library(foreach)
library(parallel)

data("DS14")
data<-DS14[,3:5] # for testing I only use 3 variables

source("C:/Users/.../code to apply function fit_skewnorm (Kolbe et al., 2021).R")
# Kolbe et al. for reference: https://doi.org/10.3390/psych3040037                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
# see Appendix B

allresults_skew <- replicate(ncol(data)-1, matrix(NA,ncol(data),9), simplify = FALSE)
for(p in 1:ncol(data)){
  for(q in 2:ncol(data)){
    if(q<=p){
      next}
    tryCatch({ # a function to continue with loop in case of errors
      obsn = table(data[,p], data[,q])
      ncats1 = nrow(obsn)
      ncats2 = ncol(obsn)
      ntot = sum(obsn)
      obsp = obsn/ntot
      proportions2 = matrix(colSums(obsp), 1, ncats2)
      proportions1 = matrix(rowSums(obsp), ncats1 , 1)
      premultiplier = matrix(0, ncats1, ncats1)
      for(l in 1:ncats1)for(m in 1:l)premultiplier[l,m] = 1
      postmultiplier = matrix(0, ncats2, ncats2)
      for(l in 1:ncats2)for(m in l:ncats2)postmultiplier[l,m] = 1
      cumulprops2 = proportions2 %*% postmultiplier
      cumulprops1 = premultiplier %*% proportions1
      nthresholds1 = ncats1 - 1
      nthresholds2 = ncats2 - 1
      thresholds1 = matrix(0, 1, nthresholds1)
      for(l in 1:nthresholds1)thresholds1[l] = qnorm(cumulprops1[l])
      thresholds2 = matrix(0, 1, nthresholds2)
      for(l in 1:nthresholds2)thresholds2[l] = qnorm(cumulprops2[l])
      pcorr = polycor::polychor(obsn)
      results_fit = fit_skewnorm(c("th1" = thresholds1, "th2" = thresholds2, "corr" = pcorr, "alpha" = c(2 ,2)))
      allresults_skew[[p]][q,1] <- p
      allresults_skew[[p]][q,2] <- q
      allresults_skew[[p]][q,3] <- results_fit[,1]
      allresults_skew[[p]][q,4] <- results_fit[,2]
      allresults_skew[[p]][q,5] <- results_fit[,3]
      allresults_skew[[p]][q,6] <- results_fit[,4]
      allresults_skew[[p]][q,7] <- results_fit[,5]
      allresults_skew[[p]][q,8] <- results_fit[,6]
      allresults_skew[[p]][q,9] <- results_fit[,7]
    }, error=function(e){cat("ERROR :",conditionMessage(e), "\n")}) # part of tryCatch
  }
}

然后,allresults_skew 是:

[[1]]
     [,1] [,2]     [,3] [,4]              [,5]      [,6] [,7]      [,8]      [,9]
[1,]   NA   NA       NA   NA                NA        NA   NA        NA        NA
[2,]    1    2 19.97874   13 0.095741675130554 0.2705112    0 1.4656923 0.7528304
[3,]    1    3 65.49704   13 0.000000005354567 0.8426818    0 0.2512463 2.2963329

[[2]]
     [,1] [,2]     [,3] [,4]        [,5]      [,6] [,7]      [,8]      [,9]
[1,]   NA   NA       NA   NA          NA        NA   NA        NA        NA
[2,]   NA   NA       NA   NA          NA        NA   NA        NA        NA
[3,]    2    3 31.14632   13 0.003209404 0.2753952    0 0.7247398 0.5957852

我当前的嵌套 foreach 循环如下所示:

allresults_skew <- replicate(ncol(data)-1, matrix(NA,ncol(data),9), simplify = FALSE)
no_cores <- detectCores(logical = TRUE)
cl <- makeCluster(no_cores-1)
registerDoParallel(cl)
getDoParWorkers()
foreach(i = 1:ncol(data),.combine = 'cbind') %:% 
  foreach(j = 2:ncol(data), .combine = 'rbind') %dopar% {
    if(j<=i){
      return(NA)}
    tryCatch({ # a function to continue with loop in case of errors
      #progress(i, ncol(data)-1)
      obsn = table(data[,i], data[,j])
      ncats1 = nrow(obsn)
      ncats2 = ncol(obsn)
      ntot = sum(obsn)
      obsp = obsn/ntot
      proportions2 = matrix(colSums(obsp), 1, ncats2)
      proportions1 = matrix(rowSums(obsp), ncats1 , 1)
      premultiplier = matrix(0, ncats1, ncats1)
      for(l in 1:ncats1)for(m in 1:l)premultiplier[l,m] = 1
      postmultiplier = matrix(0, ncats2, ncats2)
      for(l in 1:ncats2)for(m in l:ncats2)postmultiplier[l,m] = 1
      cumulprops2 = proportions2 %*% postmultiplier
      cumulprops1 = premultiplier %*% proportions1
      nthresholds1 = ncats1 - 1
      nthresholds2 = ncats2 - 1
      thresholds1 = matrix(0, 1, nthresholds1)
      for(l in 1:nthresholds1)thresholds1[l] = qnorm(cumulprops1[l])
      thresholds2 = matrix(0, 1, nthresholds2)
      for(l in 1:nthresholds2)thresholds2[l] = qnorm(cumulprops2[l])
      pcorr = polycor::polychor(obsn)
      results_fit = fit_skewnorm(c("th1" = thresholds1, "th2" = thresholds2, "corr" = pcorr, "alpha" = c(2 ,2)))
      allresults_skew[[i]][j,1] <- i
      allresults_skew[[i]][j,2] <- j
      allresults_skew[[i]][j,3] <- results_fit[,1]
      allresults_skew[[i]][j,4] <- results_fit[,2]
      allresults_skew[[i]][j,5] <- results_fit[,3]
      allresults_skew[[i]][j,6] <- results_fit[,4]
      allresults_skew[[i]][j,7] <- results_fit[,5]
      allresults_skew[[i]][j,8] <- results_fit[,6]
      allresults_skew[[i]][j,9] <- results_fit[,7]
    }, error=function(e){cat("ERROR :",conditionMessage(e), "\n")}) # part of tryCatch
    NULL
    }
stopCluster(cl)

这些 foreach 循环运行后,我得到这个矩阵:

              [,1]      [,2] [,3]
result.1 0.7528304        NA   NA
result.2 2.2963329 0.5957852   NA

并询问 allresults_skew,给我:

[[1]]
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,]   NA   NA   NA   NA   NA   NA   NA   NA   NA
[2,]   NA   NA   NA   NA   NA   NA   NA   NA   NA
[3,]   NA   NA   NA   NA   NA   NA   NA   NA   NA

[[2]]
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,]   NA   NA   NA   NA   NA   NA   NA   NA   NA
[2,]   NA   NA   NA   NA   NA   NA   NA   NA   NA
[3,]   NA   NA   NA   NA   NA   NA   NA   NA   NA

因此,foreach 循环只是给出 for 循环最后一列的值,但只是在代码运行之后。使用 allresults_skew 矩阵仍然完全不适用。 如果有人可以帮助我并告诉我要更改什么,我将不胜感激。

我也不确定是否在两个 foreach 循环中选择 .combine = 'c'、'rbind' 或 'cbind'。但我认为这并不能解释为什么代码没有生成包含 3 x 9 矩阵的列表。

【问题讨论】:

  • 我找到了适合我的解决方案:

标签: list for-loop parallel-foreach


【解决方案1】:

我找到了适合我的解决方案:

allresults_skew <- foreach(i = 1:ncol(data)) %:% foreach(j = 2:ncol(data)) %dopar% {
    if(j<=i){
      return(NA)}
    tryCatch({ # a function to continue with loop in case of errors
      #progress(i, ncol(data)-1)
      obsn = table(data[,i], data[,j])
      ncats1 = nrow(obsn)
      ncats2 = ncol(obsn)
      ntot = sum(obsn)
      obsp = obsn/ntot
      proportions2 = matrix(colSums(obsp), 1, ncats2)
      proportions1 = matrix(rowSums(obsp), ncats1 , 1)
      premultiplier = matrix(0, ncats1, ncats1)
      for(l in 1:ncats1)for(m in 1:l)premultiplier[l,m] = 1
      postmultiplier = matrix(0, ncats2, ncats2)
      for(l in 1:ncats2)for(m in l:ncats2)postmultiplier[l,m] = 1
      cumulprops2 = proportions2 %*% postmultiplier
      cumulprops1 = premultiplier %*% proportions1
      nthresholds1 = ncats1 - 1
      nthresholds2 = ncats2 - 1
      thresholds1 = matrix(0, 1, nthresholds1)
      for(l in 1:nthresholds1)thresholds1[l] = qnorm(cumulprops1[l])
      thresholds2 = matrix(0, 1, nthresholds2)
      for(l in 1:nthresholds2)thresholds2[l] = qnorm(cumulprops2[l])
      pcorr = polycor::polychor(obsn)
      results_fit = fit_skewnorm(c("th1" = thresholds1, "th2" = thresholds2, "corr" = pcorr, "alpha" = c(2 ,2)))
      }, error=function(e){cat("ERROR :",conditionMessage(e), "
")}) # part of tryCatch
    #NULL
    }
stopCluster(cl)

然后,使用

allresults_skew0 <- unlist(allresults_skew, recursive = FALSE)
allresults_skew0 <- Reduce(rbind,allresults_skew0)

给我

     chisq df                 p      corr conv    alpha1    alpha2
1 19.97874 13 0.095741675130554 0.2705112    0 1.4656923 0.7528304
2 65.49704 13 0.000000005354567 0.8426818    0 0.2512463 2.2963329
3       NA NA                NA        NA   NA        NA        NA
4 31.14632 13 0.003209403883258 0.2753952    0 0.7247398 0.5957852
5       NA NA                NA        NA   NA        NA        NA
6       NA NA                NA        NA   NA        NA        NA

【讨论】:

    猜你喜欢
    • 2013-05-24
    • 2015-07-15
    • 1970-01-01
    • 1970-01-01
    • 2012-05-16
    • 2019-07-13
    • 2016-05-28
    • 2020-03-17
    • 1970-01-01
    相关资源
    最近更新 更多