2014-12-23 7 views
5

Mi scuso se esiste già una risposta per questo ... Ho cercato ma non sono riuscito a trovarne uno.Conversione dei numeri dei fattori in numeri

Sto provando a convertire una matrice di fattori in una matrice di numeri che corrisponde a ciascuno dei valori dei fattori per la colonna. Semplice, vero? Eppure mi sono imbattuto in una serie di problemi molto strani quando provo a farlo.

Lasciatemi spiegare. Ecco un set di dati campione:

demodata2 <- matrix(c("A","B","B","C",NA,"A","B","B",NA,"C","A","B",NA,"B",NA,"C","A","B",NA,NA,NA,"B","C","A","B","B",NA,"B","B",NA,"B","B",NA,"C","A",NA), nrow=6, ncol=6) 
democolnames <- c("Q","R","S","T","U","W") 
colnames(demodata2) <- democolnames 

Cedendo:

 Q R S T U W 
[1,] "A" "B" NA NA "B" "B" 
[2,] "B" "B" "B" NA "B" "B" 
[3,] "B" NA NA NA NA NA 
[4,] "C" "C" "C" "B" "B" "C" 
[5,] NA "A" "A" "C" "B" "A" 
[6,] "A" "B" "B" "A" NA NA 

Ok. Quindi quello che voglio è questo:

 Q R S T U W 
1 1 2 <NA> <NA> 1 2 
2 2 2 2 <NA> 1 2 
3 2 <NA> <NA> <NA> <NA> <NA> 
4 3 3 3 2 1 3 
5 <NA> 1 1 3 1 1 
6 1 2 2 1 <NA> <NA> 

Nessun problema. Proviamo as.numeric(demodata2)

> as.numeric(demodata2) 
[1] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA 
[30] NA NA NA NA NA NA NA 
Warning message: 
NAs introduced by coercion 

Meno soddisfacente. Proviamo solo una colonna ...

> as.numeric(demodata2[,3]) 
[1] NA NA NA NA NA NA 
Warning message: 
NAs introduced by coercion 

* Edit *

Questi sono in realtà dovrebbero essere fattori, non personaggi (grazie @Carl Witthöft e @smci) ... Quindi cerchiamo di fare questo in un dataframe ...

> demodata2 <- as.data.frame(demodata2) 
> as.numeric(demodata2) 
Error: (list) object cannot be coerced to type 'double' 

No. Ma aspetta ... ecco dove si fa interessante ...

> as.numeric(demodata2$S) 
[1] NA 2 NA 3 1 2 

Beh, questo è giusto. Cerchiamo di convalidare le colonne di chiamata per numero:

> as.numeric(demodata2[,3]) 
[1] NA 2 NA 3 1 2 

Ok. Quindi posso fare questo colonna per colonna assemblando la mia nuova matrice iterando attraverso ncol volte ... ma c'è un modo migliore?

E perché affiora quando è in forma matriciale, al contrario del frame dati? < - modifica in realtà, questo è ora abbastanza ovvio ... nella forma matrice, questi sono caratteri, non fattori. Colpa mia. La domanda riguarda ancora il dataframe, sebbene ...

Grazie! (e indicarmi una risposta esistente è assolutamente soddisfacente)

+4

Il vostro esempio è ** non ** fattori. Stai attento alla tua nomenclatura. –

+1

L'esempio è una matrice di stringhe, non di fattori. Le stringhe non hanno alcun livello di fattore, ecc. – smci

+0

Le mie scuse. Questa domanda è iniziata con un set di dati importato, in cui le stringhe vengono automaticamente considerate fattori (se non diversamente specificato). L'errore si è verificato quando ho provato a ricrearlo per l'utilizzo dello stackoverflow. – rucker

risposta

6

Sembra che la colonna U sia 2 corrispondente a "B", non 1. Si prega di chiarire.

Si potrebbe provare match()

matrix(match(demodata2, LETTERS), nrow(demodata2), dimnames=dimnames(demodata2)) 
#  Q R S T U W 
# [1,] 1 2 NA NA 2 2 
# [2,] 2 2 2 NA 2 2 
# [3,] 2 NA NA NA NA NA 
# [4,] 3 3 3 2 2 3 
# [5,] NA 1 1 3 2 1 
# [6,] 1 2 2 1 NA NA 

si potrebbe anche ottenere questo risultato con

m <- match(demodata2, LETTERS) 
attributes(m) <- attributes(demodata2) 

E poi guardare m


Aggiornamento per il set di dati rivisti:

per i dati aggiornati, provare

demodata2[] <- lapply(demodata2, as.numeric) 
demodata2 
# Q R S T U W 
# 1 1 2 NA NA 1 2 
# 2 2 2 2 NA 1 2 
# 3 2 NA NA NA NA NA 
# 4 3 3 3 2 1 3 
# 5 NA 1 1 3 1 1 
# 6 1 2 2 1 NA NA 

Ora avete la 1 nella colonna U perché ogni colonna è scomposto singolarmente e quindi B è il primo (e unico) il valore in quella colonna.

+0

Splendida risposta alla domanda che ho posto ... ma a quanto pare ho fatto la domanda sbagliata. Crea prima demodata2 in un frame di dati (che mette automaticamente i campi dei caratteri in fattori) e poi hai la domanda che * intendevo * chiedere. Grazie mille, e spero che tu possa aiutare con questa ulteriore sfida. – rucker

+1

@rucker: è ancora più semplice per i tuoi dati aggiornati. Do 'demodata2 [] <- lapply (demodata2, as.numeric)' Ora hai gli 1 nella colonna 'U' perché ogni colonna è fattorizzata individualmente e quindi B è il primo (e unico) valore –

+0

Grazie mille! Semplice? Forse. Ma stavo andando in giro su questo, quindi il tuo aiuto è molto apprezzato. – rucker

3

o utilizzando dim<-

`dim<-`(as.numeric(factor(demodata2)), c(nrow(demodata2), ncol(demodata2))) 
#  [,1] [,2] [,3] [,4] [,5] [,6] 
# [1,] 1 2 NA NA 2 2 
# [2,] 2 2 2 NA 2 2 
# [3,] 2 NA NA NA NA NA 
# [4,] 3 3 3 2 2 3 
# [5,] NA 1 1 3 2 1 
# [6,] 1 2 2 1 NA NA 

Se è necessario i nomi di colonna, you''ll hanno a che fare questo in due fasi, come in

Res <- `dim<-`(as.numeric(factor(demodata2)), c(nrow(demodata2), ncol(demodata2))) 
colnames(Res) <- colnames(demodata2) 
+0

Un altro modo per riscrivere la tua riga: 'matrice (come.numeric (fattore (demodata2)), ncol = ncol (demodata2))' – nicola

+0

@David Arenburg : Splendida risposta alla domanda che ho posto ... ma a quanto pare ho fatto la domanda sbagliata. Crea prima demodata2 in un frame di dati (che mette automaticamente i campi dei caratteri in fattori) e poi hai la domanda che * intendevo * chiedere. Grazie mille, e spero che tu possa aiutare con questa ulteriore sfida. – rucker

4

Meccanicamente, questo è molto simile a quello 'dim<-' risposta. Un po 'più trasparente, ma probabilmente meno efficiente (forse?).

matrix(as.numeric(factor(demodata2)), ncol = ncol(demodata2)) 

    [,1] [,2] [,3] [,4] [,5] [,6] 
[1,] 1 2 NA NA 2 2 
[2,] 2 2 2 NA 2 2 
[3,] 2 NA NA NA NA NA 
[4,] 3 3 3 2 2 3 
[5,] NA 1 1 3 2 1 
[6,] 1 2 2 1 NA NA 
+0

Manca una parentesi ... –

+0

Whoops, grazie. Risulta anche che 'as.vector()' non è necessario. – Gregor

+0

Suppongo che sarebbe più efficiente di "<-dim' semplicemente perché saltando la parte' nrow', volevo solo essere un po 'lucido con esso :) –

2
apply(demodata2, 2, function(x) 
      as.numeric(factor(x ,levels=unique(as.vector(demodata2))))) 
#--------------- 
     Q R S T U W 
[1,] 1 2 NA NA 2 2 
[2,] 2 2 2 NA 2 2 
[3,] 2 NA NA NA NA NA 
[4,] 3 3 3 2 2 3 
[5,] NA 1 1 3 2 1 
[6,] 1 2 2 1 NA NA 

(ho scoperto tramite ottenere la risposta sbagliata che unique su una matrice non restituisce quello che mi aspettavo.)

+0

Meravigliosa risposta alla domanda che ho posto ... ma a quanto pare ho fatto la domanda sbagliata. Crea prima demodata2 in un frame di dati (che mette automaticamente i campi dei caratteri in fattori) e poi hai la domanda che * intendevo * chiedere. Grazie mille, e spero che tu possa aiutare con questa ulteriore sfida. – rucker