Как создать фактор из матрицы двоичного индикатора? - PullRequest
16 голосов
/ 11 октября 2011

Скажем, у меня есть следующая матрица mat, которая представляет собой матрицу двоичного индикатора для уровней A, B и C для набора из 5 наблюдений:

mat <- matrix(c(1,0,0,
                1,0,0,
                0,1,0,
                0,1,0,
                0,0,1), ncol = 3, byrow = TRUE)
colnames(mat) <- LETTERS[1:3]

> mat
     A B C
[1,] 1 0 0
[2,] 1 0 0
[3,] 0 1 0
[4,] 0 1 0
[5,] 0 0 1

Я хочу преобразовать это в единичный коэффициент, чтобы результат был эквивалентен fac, определенному как:

> fac <- factor(rep(LETTERS[1:3], times = c(2,2,1)))
> fac
[1] A A B B C
Levels: A B C

Дополнительные баллы, если вы получаете метки из имен столбцов mat, но набор числовых кодов (например, c(1,1,2,2,3)) также будет приемлем в качестве желаемого результата.

Ответы [ 5 ]

15 голосов
/ 11 октября 2011

Элегантное решение с матричным умножением (и самое короткое до сих пор):

as.factor(colnames(mat)[mat %*% 1:ncol(mat)])
8 голосов
/ 11 октября 2011

В этом решении используется аргумент arr.ind=TRUE, равный which, возвращающий совпадающие позиции в качестве местоположений массива.Затем они используются для индексации colnames:

> factor(colnames(mat)[which(mat==1, arr.ind=TRUE)[, 2]])
[1] A A B B C
Levels: A B C

Разложение на этапы:

> which(mat==1, arr.ind=TRUE)
     row col
[1,]   1   1
[2,]   2   1
[3,]   3   2
[4,]   4   2
[5,]   5   3

Используйте значения второго столбца, например which(...)[, 2] и индексcolnames:

> colnames(mat)[c(1, 1, 2, 2, 3)]
[1] "A" "A" "B" "B" "C"

И затем преобразовать в коэффициент

5 голосов
/ 11 октября 2011

Один из способов состоит в том, чтобы реплицировать имена по номеру строки и индексировать непосредственно с матрицей, затем обернуть это с помощью factor, чтобы восстановить уровни:

factor(rep(colnames(mat), each = nrow(mat))[as.logical(mat)])
[1] A A B B C
Levels: A B C

Если это из model.matrix,к именам столбцов добавлено fac, так что это должно работать так же, но удаляя лишний текст:

factor(gsub("^fac", "", rep(colnames(mat), each = nrow(mat))[as.logical(mat)]))
4 голосов
/ 11 октября 2011

Вы можете использовать что-то вроде этого:

lvls<-apply(mat, 1, function(currow){match(1, currow)})
fac<-factor(lvls, 1:3, labels=colnames(mat))
1 голос
/ 12 октября 2011

Вот еще один

factor(rep(colnames(mat), colSums(mat)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...