Putting values into a matrix only for even or odd numbered rows

Viewed 84

I am trying to specifically insert certain characters (the alphabet) into a matrix in R. Here is what I have so far.

M2 = matrix(nrow=100, ncol=26)

for (i in (1:nrow(M2)))
{
  for (j in (1:ncol(M2)))
  {
    if (i==1)
    M2[i, ] <- LETTERS
  }
  {
    if (i==2)
      M2[i, ] <- rev(LETTERS)
  }
}
M2
##        [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13]
##   [1,] "A"  "B"  "C"  "D"  "E"  "F"  "G"  "H"  "I"  "J"   "K"   "L"   "M"  
##   [2,] "Z"  "Y"  "X"  "W"  "V"  "U"  "T"  "S"  "R"  "Q"   "P"   "O"   "N"  
##   [3,] NA   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA   
##   [4,] NA   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA   
##   [5,] NA   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA   
##   [6,] NA   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA   
##   [7,] NA   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA   
##   [8,] NA   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA   
##   [9,] NA   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA   
##  [10,] NA   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA   

This works quite well so far, but I need every odd numbered row (1, 3, 5, etc. up to 100) to have the letters and every even row up to 100 to have the rev(LETTERS). What would I need to replace the if== section with to achieve this?

1 Answers

We can use rep to replicate the desired sequence of letters and then use matrix to arrange them in the desired structure.

my_sequence <- c(LETTERS, rev(LETTERS))
M2 <- matrix(rep(my_sequence, 50), byrow = T, nrow = 100)

       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13]
  [1,] "A"  "B"  "C"  "D"  "E"  "F"  "G"  "H"  "I"  "J"   "K"   "L"   "M"  
  [2,] "Z"  "Y"  "X"  "W"  "V"  "U"  "T"  "S"  "R"  "Q"   "P"   "O"   "N"  
  [3,] "A"  "B"  "C"  "D"  "E"  "F"  "G"  "H"  "I"  "J"   "K"   "L"   "M"  
  [4,] "Z"  "Y"  "X"  "W"  "V"  "U"  "T"  "S"  "R"  "Q"   "P"   "O"   "N"  
  [5,] "A"  "B"  "C"  "D"  "E"  "F"  "G"  "H"  "I"  "J"   "K"   "L"   "M"  
  [6,] "Z"  "Y"  "X"  "W"  "V"  "U"  "T"  "S"  "R"  "Q"   "P"   "O"   "N"  
... 94 more rows and 13 more columns ...

Generally, one should take advantage of R's vectorization, since vectors will usually be faster than loops. But if you wanted to implement a loop-based solution for reasons not explained in your question, you could do it the following way. Note that (i %% 2) equals zero for even rows, giving us a nice shortcut:

  M2 <- matrix(NA, nrow=100, ncol=26)
  
  for (i in 1:nrow(M2)) {

    if (i %% 2 == 0) {
      M2[i, ] <- rev(LETTERS)
    } else {
      M2[i, ] <- LETTERS
    }
  }

Or, if you absolutely had to insert each element one at a time via a nested loop, you could do it this way (but I really recommend that you don't):

  M2 <- matrix(NA, nrow=100, ncol=26)
  
  for (i in 1:nrow(M2)) {

    if (i %% 2 == 0) {
      for (j in 1:26) {
        M2[i, j] <- rev(LETTERS)[j]
      }
    } else {
      for (j in 1:26) {
        M2[i, j] <- LETTERS[j]
      }
    }
  }

Your follow-up question:

how would I do this procedure, but with numbers 1 to 100 alternating with numbers 100 to 1 for the columns? (nested loops required)

M2 <- matrix(NA, nrow=100, ncol=100)

for (i in 1:ncol(M2)) {

  if (i %% 2 == 0) {
    for (j in 1:100) {
      M2[j, i] <- 101 - j
    }
  } else {
    for (j in 1:100) {
      M2[j, i] <- j
    }
  }
}

     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15] [,16]
[1,]    1  100    1  100    1  100    1  100    1   100     1   100     1   100     1   100
[2,]    2   99    2   99    2   99    2   99    2    99     2    99     2    99     2    99
[3,]    3   98    3   98    3   98    3   98    3    98     3    98     3    98     3    98
[4,]    4   97    4   97    4   97    4   97    4    97     4    97     4    97     4    97
[5,]    5   96    5   96    5   96    5   96    5    96     5    96     5    96     5    96
[6,]    6   95    6   95    6   95    6   95    6    95     6    95     6    95     6    95
... 94 more rows and 84 more columns ...

And just for completeness, the loop-free version:

matrix(rep(c(1:100, 100:1), 50), ncol = 100)
Related