Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

subtract a constant vector from each row in a matrix in r

Tags:

r

vector

matrix

I have a matrix with 5 columns and 4 rows. I also have a vector with 3 columns. I want to subtract the values in the vector from columns 3,4 and 5 respectively at each row of the matrix.

b <- matrix(rep(1:20), nrow=4, ncol=5)      [,1] [,2] [,3] [,4] [,5] [1,]    1    5    9   13   17 [2,]    2    6   10   14   18 [3,]    3    7   11   15   19 [4,]    4    8   12   16   20  c <- c(5,6,7) 

to get

     [,1] [,2] [,3] [,4] [,5] [1,]    1    5    4    7   10 [2,]    2    6    5    8   11 [3,]    3    7    6    9   12 [4,]    4    8    7   10   13 
like image 640
user3651829 Avatar asked Jul 01 '14 23:07

user3651829


People also ask

How do you subtract a constant from a matrix?

If the second operand is a scalar, that scalar is subtracted from each element in the first matrix. In order to subtract a scalar r from the diagonal elements of a matrix A, use A - r*eye(size(A)).

How do you subtract elements from a vector in R?

To subtract all values in a vector from all values in another vector in R, we can use sapply function with subtraction sign.

How do I subtract two rows in R?

Method 1 : Using diff() method diff() method in base R is used to find the difference among all the pairs of consecutive rows in the R dataframe. It returns a vector with the length equivalent to the length of the input column – 1.


2 Answers

This is exactly what sweep was made for:

b <- matrix(rep(1:20), nrow=4, ncol=5) x <- c(5,6,7)  b[,3:5] <- sweep(b[,3:5], 2, x) b  #     [,1] [,2] [,3] [,4] [,5] #[1,]    1    5    4    7   10 #[2,]    2    6    5    8   11 #[3,]    3    7    6    9   12 #[4,]    4    8    7   10   13 

..or even without subsetting or reassignment:

sweep(b, 2, c(0,0,x)) 
like image 87
thelatemail Avatar answered Sep 29 '22 10:09

thelatemail


Perhaps not that elegant, but

b <- matrix(rep(1:20), nrow=4, ncol=5) x <- c(5,6,7)  b[,3:5] <- t(t(b[,3:5])-x) 

should do the trick. We subset the matrix to change only the part we need, and we use t() (transpose) to flip the matrix so simple vector recycling will take care of subtracting from the correct row.

If you want to avoid the transposed, you could do something like

b[,3:5] <- b[,3:5]-x[col(b[,3:5])] 

as well. Here we subset twice, and we use the second to get the correct column for each value in x because both those matrices will index in the same order.

I think my favorite from the question that @thelatemail linked was

b[,3:5] <- sweep(b[,3:5], 2, x, `-`) 
like image 42
MrFlick Avatar answered Sep 29 '22 10:09

MrFlick