para - ¿Cómo crear un factor a partir de una matriz de indicadores binarios?
que es un indicador (5)
Aquí hay otra.
factor(rep(colnames(mat), colSums(mat)))
Digamos que tengo la siguiente matriz matricial, que es una matriz de indicador binario para los niveles A
, B
y C
para un conjunto de 5 observaciones:
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
Quiero convertir eso en un solo factor tal que la salida sea equivalente a fac
define como:
> fac <- factor(rep(LETTERS[1:3], times = c(2,2,1)))
> fac
[1] A A B B C
Levels: A B C
Puntos extra si obtiene las etiquetas de los nombres de mat
, pero un conjunto de códigos numéricos (por ejemplo, c(1,1,2,2,3)
) también sería aceptable como resultado deseado.
Esta solución utiliza el argumento arr.ind=TRUE
del which
, devolviendo las posiciones coincidentes como ubicaciones de matriz. Estos se utilizan para indexar los colnames
los colnames
:
> factor(colnames(mat)[which(mat==1, arr.ind=TRUE)[, 2]])
[1] A A B B C
Levels: A B C
Descomponiéndose en pasos:
> which(mat==1, arr.ind=TRUE)
row col
[1,] 1 1
[2,] 2 1
[3,] 3 2
[4,] 4 2
[5,] 5 3
Utilice los valores de la segunda columna, es decir, which(...)[, 2]
y los colnames
índices:
> colnames(mat)[c(1, 1, 2, 2, 3)]
[1] "A" "A" "B" "B" "C"
Y luego convertir a un factor
Podrías usar algo como esto:
lvls<-apply(mat, 1, function(currow){match(1, currow)})
fac<-factor(lvls, 1:3, labels=colnames(mat))
Solución elegante con la multiplicación de matrices (y la más corta hasta ahora):
as.factor(colnames(mat)[mat %*% 1:ncol(mat)])
Una forma es replicar los nombres por número de fila e índice directamente con la matriz, luego envuélvalos con factor
para restaurar los niveles:
factor(rep(colnames(mat), each = nrow(mat))[as.logical(mat)])
[1] A A B B C
Levels: A B C
Si esto es de model.matrix, los nombres de los nombres han sido prefabricados, por lo que debería funcionar igual pero eliminando el texto adicional:
factor(gsub("^fac", "", rep(colnames(mat), each = nrow(mat))[as.logical(mat)]))