簡體   English   中英

R-多個嵌套循環地獄

[英]R - multiple nested loops inferno

我想從3個向量創建矩陣列表,其中sd_vec嚴格為正:

z_vec <- c(qnorm(0.90), qnorm(0.95), qnorm(0.975))  # 95% CI, 90% CI, 80% CI
me_vec <- c(0.50, 0.25, 0.10, 0.05)
sd_vec <- rnorm(n = 9, 0.8, 0.4)
sd_vec[which(sd_vec <= 0)] <- 0.1

我的問題有兩個:

  • 如何將我的循環從1個矩陣推廣到多個矩陣? 我可以逐步創建矩陣(嵌套2個級別),但是當我嵌套所有3個級別時,索引將分解。
  • 我如何才能完全避免for循環(按照此答案的精神)? 我歡迎使用sapply()等任何答案。

這是我嘗試的一個示例:

new_n <- matrix(NA, 3,4)
for(i in seq_along(z_vec)){
  for(j in seq_along(me_vec)){
    new_n[i, j] <- ((z_vec[i] * sd_vec[1]) /me_vec[j])^2
  }
}

new_n
#      [,1]  [,2]  [,3] [,4]
# [1,] 2.45  9.82  61.4  245
# [2,] 4.04 16.17 101.1  404
# [3,] 5.74 22.96 143.5  574

然后我的索引失敗:

new_n <- vector("list", length = length(sd_vec))
for(k in seq_along(sd_vec)){
  for(i in seq_along(z_vec)){
    for(j in seq_along(me_vec)){
      new_n[[k]][i, j] <- ((z_vec[i] * sd_vec[k]) /me_vec[j])^2
    }
  }
}

帶有錯誤消息Error in new_n[[k]][i, j] <- ((z_vec[i] * sd_vec[k])/me_vec[j])^2 : incorrect number of subscripts on matrix

感謝您對這個瑣碎問題的協助!

關於最后一個示例中的錯誤消息,我認為這是由於矩陣列表的初始化不正確造成的。 您可以嘗試更換

new_n <- vector("list", length = length(sd_vec))

new_n <- replicate(length(sd_vec), matrix(NA, 3, 4), simplify = FALSE)

這樣可以解決索引錯誤問題。 尋找一種優雅而緊湊的方式來重寫復雜的嵌套循環是另一個問題。 我相信SO社區很快就會提出不錯的解決方案。

更新

第一個示例中的嵌套循環可以這樣重寫:

new_n <- t(sapply(seq_along(z_vec), function(x,y) ((z_vec[x] * sd_vec[1]) / me_vec[y])^2))

此處說明如何創建矩陣列表,並且要計算沒有for循環的每個矩陣,我們可以使用“外部”:

z_vec <- c(qnorm(0.90), qnorm(0.95), qnorm(0.975))  # 95% CI, 90% CI, 80% CI
me_vec <- c(0.50, 0.25, 0.10, 0.05)
sd_vec <- rnorm(n = 9, 0.8, 0.4)
sd_vec[which(sd_vec <= 0)] <- 0.1

new_n <- list()

for ( k in seq_along(sd_vec) )
{
  new_n[[k]] <- outer( z_vec*sd_vec[k], me_vec,
                       FUN = function(x,y){ (x/y)^2 } )
}

使用“外部”兩次,就可以在沒有任何for循環的情況下生成包含與“ new_n”相同矩陣的3維數組:

A <- outer( outer( sd_vec, z_vec, "*"),
            me_vec, function(x,y){ (x/y)^2 } )

然后,對於每個“ k”,“ new_n [[k]]”與“ A [k ,,]”相同。 為了擺脫最后一個“ for”循環,我們可以使用庫“ plyr”中的函數“ alply”將三維數組變成矩陣列表

library(plyr)

z_vec <- c(qnorm(0.90), qnorm(0.95), qnorm(0.975))  # 95% CI, 90% CI, 80% CI
me_vec <- c(0.50, 0.25, 0.10, 0.05)
sd_vec <- rnorm(n = 9, 0.8, 0.4)
sd_vec[which(sd_vec <= 0)] <- 0.1

A <- outer( outer( sd_vec, z_vec, "*"),
            me_vec, function(x,y){ (x/y)^2 } )

new_n <- alply(A,1)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM