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

Time:10-27

I have an O = n x m matrix containing 0s and 1s that I have to transform into m matrices of M_j = n x n dimension. Each of those M_j matrices will have value 1 if: element i of column j of the O matrix is equal to 1 & element k of column j of the O matrix is equal to 0; and will have value 0 otherwise. I've managed to create a script using a triple for-loop and an if statement in R that does this quite easily, but I'm sure there must be a much more efficient way to do this. However, I can't really think of how to vectorize/use sapply/ something else. Any suggestions?

My sample code:

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
  
}

Thank you very much in advance!!

CodePudding user response:

Yes, your triple loop can be replaced with the following one-liner:

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

CodePudding user response:

You inner for loops are doing an outer:

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