我可以在 R 中使用 if 语句避免三重 for 循环吗?

Can I avoid a triple for-loop with an if statement in R?

我有一个包含 0 和 1 的 O = n x m 矩阵,我必须将其转换为 M_j = n x n 维的 m 个矩阵。在以下情况下,每个 M_j 矩阵的值为 1: O矩阵第j列元素i等于1 & O矩阵第j列元素k等于0; 否则值为 0。 我已经成功地使用三重 for 循环和 R 中的 if 语句创建了一个脚本,它可以很容易地做到这一点,但我确信必须有一种更有效的方法来做到这一点。但是,我真的想不出如何 vectorize/use 应用/其他东西。 有什么建议吗?

我的示例代码:

o <- data.frame(s1 = c(1,0,0),
                s2 = c(0,1,1),
                s3 = c(1,0,1),
                s4 = c(0,1,1))


#### MATRICES M (4 matrices of 3x3) ----
m <- list()
n_ocup <- nrow(o)
n_skill <- ncol(o)

for (i in 1:n_skill){
  
  print(paste0("########### M", i, " ###########"))
  temp_m <- matrix(nrow = n_ocup, ncol = n_ocup, 0)
  temp_o <- o[,i]
  
  for (j in 1:nrow(temp_m)){
    for (k in 1:ncol(temp_m)){
      
      if (temp_o[j,1]==1 & temp_o[k,1]==0){
        temp_m[k,j] <- 1 #seems backwards but it's OK
      }
    }
  }

  m[[i]] <- temp_m
  
}

非常感谢您!!

是的,您的三重循环可以替换为以下单行:

lapply(o, function(x) outer(x, x, function(a, b) as.numeric(b == 1 & a == 0)))
#> $s1
#>      [,1] [,2] [,3]
#> [1,]    0    0    0
#> [2,]    1    0    0
#> [3,]    1    0    0
#> 
#> $s2
#>      [,1] [,2] [,3]
#> [1,]    0    1    1
#> [2,]    0    0    0
#> [3,]    0    0    0
#> 
#> $s3
#>      [,1] [,2] [,3]
#> [1,]    0    0    0
#> [2,]    1    0    1
#> [3,]    0    0    0
#> 
#> $s4
#>      [,1] [,2] [,3]
#> [1,]    0    1    1
#> [2,]    0    0    0
#> [3,]    0    0    0

您的内部 for 循环正在执行 outer:

m <- lapply(o, function(x) {outer(1 - x, x)})