# 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 R

In 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
```