Ответ 1
Элегантное решение с матричным умножением (и самым коротким до сих пор):
as.factor(colnames(mat)[mat %*% 1:ncol(mat)])
Скажем, у меня есть следующая матрица 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)
) также будет приемлемым в качестве желаемого результата.
Элегантное решение с матричным умножением (и самым коротким до сих пор):
as.factor(colnames(mat)[mat %*% 1:ncol(mat)])
В этом решении используется аргумент 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]
и index colnames
:
> colnames(mat)[c(1, 1, 2, 2, 3)]
[1] "A" "A" "B" "B" "C"
А затем преобразуйте в коэффициент
Один из способов - копировать имена по номеру строки и индексировать непосредственно с помощью матрицы, а затем обернуть это с помощью factor
, чтобы восстановить уровни:
factor(rep(colnames(mat), each = nrow(mat))[as.logical(mat)])
[1] A A B B C
Levels: A B C
Если это из model.matrix, у colnames есть fac
prepended, и поэтому это должно работать одинаково, но удаление дополнительного текста:
factor(gsub("^fac", "", rep(colnames(mat), each = nrow(mat))[as.logical(mat)]))
Вы можете использовать что-то вроде этого:
lvls<-apply(mat, 1, function(currow){match(1, currow)})
fac<-factor(lvls, 1:3, labels=colnames(mat))
Вот еще один
factor(rep(colnames(mat), colSums(mat)))