How to create a factor from a binary indicator matrix?

Elegant solution with matrix multiplication (and shortest up to now).

Elegant solution with matrix multiplication (and shortest up to now): as. Factor(colnames(mat)mat %*% 1:ncol(mat)).

Seq_len(ncol(mat)) would be more robust, but as your answer is simple, elegant and deals with the possibility of an unordered indicator matrix, you get the Accept. The ordering could easily be solved in the other solutions, but that will add to their length. Thanks Thomas.

– Gavin Simpson Oct 12 '11 at 8:46 @Gavin, thanks. Regarding robustness - how is seq_len more robust? You mean the case when ncol(mat) == 0?

In that case it wouldn't work either. – Tomas Oct 12 '11 at 9:46 I know, but 1:ncol(mat) gives 1,0 in that case, and seq_len(ncol(mat)) returns a zero length integer vector - which is the right answer. You could imagine cases where 1:ncol(mat) might work but give the wrong answer whilst seq_len(ncol(mat)) would cause it to fail appropriately.

I'm just always wary of 1:foo where foo is computed. – Gavin Simpson Oct 12 '11 at 10:47 @Gavin, thanks, good note. But as I tested it now, you don't need to worry with ncol().

It seems it will never return something smaller than 1 without an error (which is quite expected behaviour). – Tomas Oct 12 '11 at 11:16.

This solution makes use of the arr. Ind=TRUE argument of which, returning the matching positions as array locations. These are then used to index the colnames: > factor(colnames(mat)which(mat==1, arr.

Ind=TRUE), 2) 1 A A B B C Levels: A B C Decomposing into steps: > which(mat==1, arr. Ind=TRUE) row col 1, 1 1 2, 2 1 3, 3 2 4, 4 2 5, 5 3 Use the values of the second column, i.e. Which(...), 2 and index colnames: > colnames(mat)c(1, 1, 2, 2, 3) 1 "A" "A" "B" "B" "C" And then convert to a factor.

Will not work if the factors are not ordered, try it on matrix mat2 = rbind(mat, c(1, 0, 0)). – Tomas Oct 12 '11 at 8:00 The problem is that which() is doing it by columns, not by rows. You can fix it by transposing it (swapping rows/columns): factor(colnames(mat2)which(t(mat2)==1, arr.

Ind=TRUE),1). I don't know, maybe there is a better way how to tell which() to go by rows, not by columns! – Tomas Oct 12 '11 at 10:35.

One way is to replicate the names out by row number and index directly with the matrix, then wrap that with factor to restore the levels: factor(rep(colnames(mat), each = nrow(mat))as. Logical(mat)) 1 A A B B C Levels: A B C If this is from model. Matrix, the colnames have fac prepended, and so this should work the same but removing the extra text: factor(gsub("^fac", "", rep(colnames(mat), each = nrow(mat))as.

Logical(mat))).

Again, it will not work if the factors are not ordered, try it on matrix mat2 = rbind(mat, c(1, 0, 0)). – Tomas Oct 12 '11 at 8:02.

Here is another one factor(rep(colnames(mat), colSums(mat))).

1 Will not work if the factors are not ordered, try it on matrix mat2 = rbind(mat, c(1, 0, 0)). – Tomas Oct 12 '11 at 8:01.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions