# User:Timothee Flutre/Notebook/Postdoc/2012/02/17

Project name | Main project page Previous entry Next entry |

## How to subtract a vector from a matrix in RIn R, matrix algebra is very fast, so it's better to use it. But it's not always clear how to subtract a vector from each row of a matrix, or from each column, especially when the matrix is square. (When the matrix is square, R will always successfully return you an answer but it may not correspond to what you ask! While if the matrix is not square, R will run successfully or not, depending on the length of the vector). - Key fact: internally,
**R records a matrix as a long vector corresponding to the concatenation of the columns**(vectorization in maths).
- Before anything else, let's define our dummy data. Here is my matrix:
m <- matrix(1:4, nrow=2, ncol=2, byrow=TRUE) m [,1] [,2] [1,] 1 2 [2,] 3 4 And here is my vector: v <- c(1, 5) v [1] 1 5 - We can easily check that R records a matrix as a concatenation of its columns:
m[1] [1] 1 m[2] [1] 3 m[3] [1] 2 m[4] [1] 4 - First, I want to
**subtract v from each column of m**. Here is what I want to obtain:
[,1] [,2] [1,] 0 1 [2,] -2 -1 The following simple command gives me what I want: m - v [,1] [,2] [1,] 0 1 [2,] -2 -1 We could also have done it with apply: apply(m, 2, "-", v) [,1] [,2] [1,] 0 1 [2,] -2 -1 Or with sweep: sweep(m, 1, v, "-") [,1] [,2] [1,] 0 1 [2,] -2 -1 Note that the parameter MARGIN in "apply" should be put to 2 to operate on the columns, while in "sweep" it should be put to 1... - Second, I want to
**subtract v from each row of m**. Here is what I want to obtain:
[,1] [,2] [1,] 0 -3 [2,] 2 -1 Of course, m - v won't work here. But again, as we know how R handle matrices internally, we can use the transpose function: t(t(m)-v) [,1] [,2] [1,] 0 -3 [2,] 2 -1 We could also have use "apply" (with MARGIN=1). But wait, "transpose" is also required here! t(apply(m, 1, "-", v)) [,1] [,2] [1,] 0 -3 [2,] 2 -1 And for "sweep"? Well, it understands properly that we want to operate on rows (MARGIN=2), so it returns the results row by row... sweep(m, 2, v, "-") [,1] [,2] [1,] 0 -3 [2,] 2 -1 |