Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keep column name when filtering matrix columns

Tags:

r

matrix

I have a matrix, like the one generated with this code:

> m = matrix(data=c(1:50), nrow= 10, ncol = 5);
> colnames(m) = letters[1:5];

If I filter the columns, and the result have more than one column, the new matrix keeps the names. For example:

> m[, colnames(m) != "a"];

       b  c  d  e
 [1,] 11 21 31 41
 [2,] 12 22 32 42
 [3,] 13 23 33 43
 [4,] 14 24 34 44
 [5,] 15 25 35 45
 [6,] 16 26 36 46
 [7,] 17 27 37 47
 [8,] 18 28 38 48
 [9,] 19 29 39 49
[10,] 20 30 40 50

Notice that here, the class is still matrix:

> class(m[, colnames(m) != "a"]);
[1] "matrix"

But, when the filter lets only one column, the result is a vector, (integer vector in this case) and the column name, is lost.

> m[, colnames(m) == "a"]
[1]  1  2  3  4  5  6  7  8  9 10

> class(m[, colnames(m) == "a"]);
[1] "integer"

The name of the column is very important.

I would like to keep both, matrix structure (a one column matrix) and the column's name.

But, the column's name is more important.

I already know how to solve this by the long way (by keeping track of every case). I'm wondering if there is an elegant, enlightening solution.

like image 204
htellez Avatar asked Apr 04 '13 02:04

htellez


2 Answers

You need to set drop = FALSE. This is good practice for programatic use

drop

For matrices and arrays. If TRUE the result is coerced to the lowest possible dimension (see the examples)

m[,'a',drop=FALSE]

This will retain the names as well.

like image 139
mnel Avatar answered Sep 18 '22 17:09

mnel


You can also use subset:

m.a = subset(m, select = colnames(m) == "a")
like image 40
Alex Avatar answered Sep 20 '22 17:09

Alex