2012-12-16 21 views
12

Vorrei convertire il mio dataframe in una matrice che espande una colonna a fattore singolo in più e assegnare uno 1/0 a seconda del fattore. Per esempioConversione di fattori R in valori di matrice binaria

C1 C2 C3 
A 3 5 
B 3 4 
A 1 1 

dovrebbe girare in qualcosa di simile

C1_A C1_B C2 C3 
1  0 3 5 
0  1 3 4 
1  0 1 1 

Come posso fare questo in R? Ho provato data.matrix, as.matrix che non ha restituito quello che volevo. Assegnano un valore "intero" a una colonna a fattore singolo, non c'è espansione.

risposta

15

Assumendo dat è la cornice di dati:

cbind(dat, model.matrix(~ 0 + C1, dat)) 

    C1 C2 C3 C1A C1B 
1 A 3 5 1 0 
2 B 3 4 0 1 
3 A 1 1 1 0 

Questa soluzione funziona con qualsiasi numero di livelli di fattore e senza specificare manualmente i nomi delle colonne.

Se si desidera escludere la colonna C1, è possibile utilizzare questo comando:

cbind(dat[-1], model.matrix(~ 0 + C1, dat)) 
+10

L'OP sembra voler 'model.matrix (~. + 0, dat)'. – Roland

+0

@Roland Buona idea +1. Questo sarebbe ancora più facile. –

+1

@Sven, questo ha funzionato, grazie. Mantiene comunque C1 nel risultato (oltre alle colonne C1_A, C1_B), qualche idea su come rimuovere la colonna originale? Questa è una domanda più generale però (forse), semplicemente un modo semplice per dire "dammi tutte le colonne tranne che" quello che farebbe ". – user423805

2

Chiamiamo tuo data.frame df:

library(reshape2) 
dcast(df,C2*C3~C1,fill=0,length) 

    C2 C3 A B 
1 1 1 1 0 
2 3 4 0 1 
3 3 5 1 0 
+1

Grazie per entrambe le risposte .. isnt c'è un modo per fare questa conversione senza specificare alcun nome di colonna, come ad esempio C1? Semplicemente ... convert (df) e gestirà i fattori. lm() e altri metodi di regressione fanno questo internamente giusto? – user423805

3
dat <- read.table(text =' C1 C2 C3 
A 3 5 
B 3 4 
A 1 1',header=T) 

Utilizzando trasformare

transform(dat,C1_A =ifelse(C1=='A',1,0),C1_B =ifelse(C1=='B',1,0))[,-1] 
    C2 C3 C1_A C1_B 
1 3 5 1 0 
2 3 4 0 1 
3 1 1 1 0 

o per ottenere ulteriori flexbility, con within

within(dat,{ 
      C1_A =ifelse(C1=='A',1,0) 
      C1_B =ifelse(C1=='B',1,0)}) 

    C1 C2 C3 C1_B C1_A 
1 A 3 5 0 1 
2 B 3 4 1 0 
3 A 1 1 0 1 
Problemi correlati