2012-07-05 13 views
6

datos Dado que se parece a:Convierte una columna factor a varias columnas booleanas

library(data.table) 
DT <- data.table(x=rep(1:5, 2)) 

me gustaría dividir estos datos en 5 columnas booleanas que indican la presencia de cada número.

que pueda hacer esto de esta manera:

new.names <- sort(unique(DT$x)) 

DT[, paste0('col', new.names) := lapply(new.names, function(i) DT$x==i), with=FALSE] 

Pero esto utiliza un molesto lapply que es probablemente más lenta que la alternativa data.table y esta solución no me parece muy "data.table-ish".

¿Existe una manera mejor y/o más rápida de crear estas nuevas columnas?

+1

¿Podría algo como 'model.matrix' ser útil? 'model.matrix (~ cols-1)' – BenBarnes

Respuesta

8

¿Qué tal model.matrix?

model.matrix(~factor(x)-1,data=DT) 

    factor(x)1 factor(x)2 factor(x)3 factor(x)4 factor(x)5 
1   1   0   0   0   0 
2   0   1   0   0   0 
3   0   0   1   0   0 
4   0   0   0   1   0 
5   0   0   0   0   1 
6   1   0   0   0   0 
7   0   1   0   0   0 
8   0   0   1   0   0 
9   0   0   0   1   0 
10   0   0   0   0   1 
attr(,"assign") 
[1] 1 1 1 1 1 
attr(,"contrasts") 
attr(,"contrasts")$`factor(x)` 
[1] "contr.treatment" 

Al parecer, se puede poner en model.matrix[.data.table para dar los mismos resultados. No estoy seguro si sería más rápido:

DT[,model.matrix(~factor(x)-1)] 
+0

Por supuesto, hay una respuesta de la base R ... ¡Gracias! – Justin

2

También hay nnet::class.ind

library(nnet) 

cbind(DT, setnames(as.data.table(DT[, class.ind(x)]),paste0('col', unique(DT$x)))) 
0
library(data.table) 
DT <- data.table(x=rep(1:5, 2)) 

# add column with id 
DT[, id := seq.int(nrow(DT))] 

# cast long table into wide 
DT.wide <- dcast(DT, id ~ x, value.var = "x", fill = 0, fun = function(x) 1) 
Cuestiones relacionadas