2014-12-23 16 views
5

Ich entschuldige mich, wenn es dafür bereits eine Antwort gibt ... Ich habe gesucht, konnte aber keine finden.Konvertieren von Faktorstufen in Zahlen

Ich versuche, eine Matrix von Faktoren in eine Matrix von Zahlen zu konvertieren, die jedem der Faktorwerte für die Spalte entspricht. Einfach, oder? Aber ich habe eine Reihe von sehr seltsamen Problemen erlebt, wenn ich das versuche.

Lassen Sie mich erklären. Hier ist ein Beispieldatensatz:

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 

Nachgeben:

 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. Also, was ich will, ist dies:

 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> 

Kein Problem. Lassen Sie uns versuchen 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 

weniger als befriedigend. Lassen Sie uns versuchen nur eine Spalte ...

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

* edit *

Diese sollen eigentlich Faktoren, nicht Zeichen (dank @Carl Witthoft und @smci) sein ... so lassen Sie uns dies machen in einen Datenrahmen ...

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

Nein. Aber warten Sie ... hier ist es interessant ...

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

Nun, das ist richtig. Lassen Sie uns validieren Ich kann dies Calling Spalten nach Nummer:

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

Ok. Also kann ich diese Spalte für Spalte meine neue Matrix assemblieren, indem ich durch ncol mal iteriere ... aber gibt es einen besseren Weg?

Und warum barf, wenn es in Matrixform ist, im Gegensatz zu Datenrahmen? - bearbeiten eigentlich, das ist jetzt ziemlich offensichtlich ... in der Matrixform, das sind Zeichen, keine Faktoren. Mein Fehler. Frage steht immer noch über den Datenrahmen, obwohl ...

Vielen Dank! (und zeigt mir eine bestehende Antwort ist völlig in Ordnung)

+4

Ihr Beispiel ist ** Nicht ** Faktoren. Sei vorsichtig mit deiner Nomenklatur. –

+1

Ihr Beispiel ist eine Matrix von Strings, keine Faktoren. Strings haben keine Faktorstufen usw. – smci

+0

Entschuldigung. Diese Frage wurde mit einem importierten Datensatz gestartet, bei dem automatisch Zeichenfolgen angenommen werden (sofern nicht anders angegeben). Der Fehler ist aufgetreten, als ich versucht habe, ihn für die Stackoverflow-Verwendung neu zu erstellen. – rucker

Antwort

6

Es scheint, dass Ihre U Spalte 2 entsprechend "B" sein sollte, nicht 1. Bitte klären Sie das.

könnten Sie versuchen, 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 

Sie auch dieses Ergebnis mit

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

bekommen konnte Und dann schauen m


Update für die überarbeitete Datensatz:

Für Ihre aktualisierten Daten, versuchen

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 

Jetzt haben Sie die 1 sind in der U Spalte, da jede Spalte einzeln berücksichtigt wird, und daher ist B der erste (und einzige) Wert in dieser Spalte.

+0

Wunderbare Antwort auf die Frage, die ich gestellt habe ... aber anscheinend habe ich die falsche Frage gestellt. Machen Sie zuerst demodata2 zu einem Datenrahmen (der die Zeichenfelder automatisch in Faktoren einfügt) und dann haben Sie die Frage, die ich * stellen wollte. Vielen Dank, und ich hoffe, dass Sie mit dieser zusätzlichen Herausforderung helfen können. – rucker

+1

@rucker - es ist noch einfacher für Ihre aktualisierten Daten. 'Demodata2 [] <- lapply (demodata2, as.numeric)' Jetzt haben Sie die 1's in der 'U'-Spalte, da jede Spalte einzeln faktorisiert wird und daher B der erste (und einzige) Wert ist –

+0

Vielen Dank! Einfach? Vielleicht. Aber ich war auf diesem Weg herum und herum, so dass Ihre Hilfe sehr geschätzt wird. – rucker

3

Oder mit 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 

Wenn Sie die Spaltennamen benötigen, you''ll haben dies als in zwei Schritten zu tun, in

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

Eine andere Möglichkeit, um Ihre Zeile umzuschreiben: 'Matrix (as.numeric (Faktor (Demodata2)), Ncol = Ncol (Demodata2))' – nicola

+0

@ David Arenburg : Wunderbare Antwort auf die Frage, die ich gestellt habe ... aber anscheinend habe ich die falsche Frage gestellt. Machen Sie zuerst demodata2 zu einem Datenrahmen (der die Zeichenfelder automatisch in Faktoren einfügt) und dann haben Sie die Frage, die ich * stellen wollte. Vielen Dank, und ich hoffe, dass Sie mit dieser zusätzlichen Herausforderung helfen können. – rucker

4

Mechanisch, das ist sehr ähnlich wie die 'dim<-' Antworten. Ein bisschen transparenter, aber wahrscheinlich weniger effizient (vielleicht?).

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

Eine Klammer fehlt ... –

+0

Whoops, danke. Stellt sich heraus das 'as.vector()' ist auch nicht notwendig. – Gregor

+0

Meine Vermutung, es wäre effizienter als '<-dim', einfach weil ich den' nrow' Teil ausließ, wollte ich nur ein bisschen glatt damit sein :) –

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 

(Ich entdeckte die falsche Antwort über bekommen, dass unique auf einer Matrix nicht das, was zurückgibt ich erwartet hatte.)

+0

Wunderbare Antwort für die Frage, die ich gestellt habe ... aber anscheinend habe ich die falsche Frage gestellt. Machen Sie zuerst demodata2 zu einem Datenrahmen (der die Zeichenfelder automatisch in Faktoren einfügt) und dann haben Sie die Frage, die ich * stellen wollte. Vielen Dank, und ich hoffe, dass Sie mit dieser zusätzlichen Herausforderung helfen können. – rucker

Verwandte Themen