2

I am asked as an exercise to use recycling to initiate a 4 by 5 matrix where the first three rows are 0's and the fourth row has 4, 8, 12, 16, 20.

I understand that recycling is defined as if the lengths of the two vectors in a mathematical operation do not match, then the shorter vector is repeated until its length matches that of the larger vector. I have tried to create a matrix through the following and other things along the same line.

x = matrix(0,nrow=4,ncol=5) + c(4,8,12,16,20) 

Of course this isn't correct so I am wondering what I am missing here. Any help is appreciated.

Henrik
  • 65,555
  • 14
  • 143
  • 159
james black
  • 122
  • 7

4 Answers4

3

When called on vector arguments, rbind returns a matrix and recycles the vectors that are too short, making for a simple and elegant solution:

rbind(0, 0, 0, c(4, 8, 12, 16, 20))

#      [,1] [,2] [,3] [,4] [,5]
# [1,]    0    0    0    0    0
# [2,]    0    0    0    0    0
# [3,]    0    0    0    0    0
# [4,]    4    8   12   16   20
Count Orlok
  • 997
  • 4
  • 13
2

If the intention is to replace the last row, use replace with row/column index

replace(matrix(0,nrow=4,ncol=5), cbind(4, 1:5), c(4,8,12,16,20))
#     [,1] [,2] [,3] [,4] [,5]
#[1,]    0    0    0    0    0
#[2,]    0    0    0    0    0
#[3,]    0    0    0    0    0
#[4,]    4    8   12   16   20

Or do the assignment

m1 <- matrix(0,nrow=4,ncol=5)
m1[nrow(m1),] <- c(4,8,12,16,20)

Or if we need to use +

matrix(0, nrow=4, ncol=5) + 
      do.call(rbind, rep(list(0, c(4, 8, 12, 16, 20)), c(3, 1)))
#     [,1] [,2] [,3] [,4] [,5]
#[1,]    0    0    0    0    0
#[2,]    0    0    0    0    0
#[3,]    0    0    0    0    0
#[4,]    4    8   12   16   20

Or another option is to multiply a logical vector recycled with a replicated vector of values to change the values to 0 and then construct the matrix

matrix(rep(c(4, 8, 12, 16, 20), each = 4) * c(FALSE, FALSE, FALSE, TRUE), 4, 5)
#     [,1] [,2] [,3] [,4] [,5]
#[1,]    0    0    0    0    0
#[2,]    0    0    0    0    0
#[3,]    0    0    0    0    0
#[4,]    4    8   12   16   20
akrun
  • 874,273
  • 37
  • 540
  • 662
2

Using modulo (%%):

matrix(1:20 * (1:20 %% 4 == 0), nrow = 4)

Written a bit more general:

nr = 4
nc = 5
v = seq(nr * nc)
matrix(v * (v %% nr == 0), nrow = nr)
Henrik
  • 65,555
  • 14
  • 143
  • 159
1

Here's another version that uses matrix multiplication with a vector:

matrix(rep(c(0,0,0,1),5),ncol=5)* c(16,12,8,4,20)


     [,1] [,2] [,3] [,4] [,5]
[1,]    0    0    0    0    0
[2,]    0    0    0    0    0
[3,]    0    0    0    0    0
[4,]    4    8   12   16   20

...and yet another version:

t(matrix(c(rep(0,15),rep(1,5)),ncol=4) * c(4,8,12,16,20))


     [,1] [,2] [,3] [,4] [,5]
[1,]    0    0    0    0    0
[2,]    0    0    0    0    0
[3,]    0    0    0    0    0
[4,]    4    8   12   16   20
Len Greski
  • 10,505
  • 2
  • 22
  • 33