709 Stimmen

Umrechnung eines Faktors in eine ganze Zahl \numeric ohne Informationsverluste?

Wenn ich einen Faktor in einen numerischen oder ganzzahligen Wert umwandle, erhalte ich die zugrunde liegenden Ebenencodes und nicht die Werte als Zahlen.

f <- factor(sample(runif(5), 20, replace = TRUE))
##  [1] 0.0248644019011408 0.0248644019011408 0.179684827337041 
##  [4] 0.0284090070053935 0.363644931698218  0.363644931698218 
##  [7] 0.179684827337041  0.249704354675487  0.249704354675487 
## [10] 0.0248644019011408 0.249704354675487  0.0284090070053935
## [13] 0.179684827337041  0.0248644019011408 0.179684827337041 
## [16] 0.363644931698218  0.249704354675487  0.363644931698218 
## [19] 0.179684827337041  0.0284090070053935
## 5 Levels: 0.0248644019011408 0.0284090070053935 ... 0.363644931698218

as.numeric(f)
##  [1] 1 1 3 2 5 5 3 4 4 1 4 2 3 1 3 5 4 5 3 2

as.integer(f)
##  [1] 1 1 3 2 5 5 3 4 4 1 4 2 3 1 3 5 4 5 3 2

Ich muss zurückgreifen auf paste um die tatsächlichen Werte zu erhalten:

as.numeric(paste(f))
##  [1] 0.02486440 0.02486440 0.17968483 0.02840901 0.36364493 0.36364493
##  [7] 0.17968483 0.24970435 0.24970435 0.02486440 0.24970435 0.02840901
## [13] 0.17968483 0.02486440 0.17968483 0.36364493 0.24970435 0.36364493
## [19] 0.17968483 0.02840901

Gibt es eine bessere Möglichkeit, einen Faktor in einen numerischen Wert umzuwandeln?

7 Stimmen

Die Stufen eines Faktors werden ohnehin als Zeichendatentyp gespeichert ( attributes(f) ), daher glaube ich nicht, dass es etwas gegen die as.numeric(paste(f)) . Vielleicht wäre es besser, darüber nachzudenken, warum Sie (in dem spezifischen Kontext) überhaupt einen Faktor erhalten, und zu versuchen, dies zu verhindern. Ist z. B. der dec Argument in read.table richtig eingestellt?

0 Stimmen

Wenn Sie einen Datenrahmen verwenden, können Sie convert from hablar verwenden. df %>% convert(num(column)) . Wenn Sie einen Faktorvektor haben, können Sie auch as_reliable_num(factor_vector)

1 Stimmen

Vielen Dank für diese Frage. Dies ist SO VIEL f

110voto

Jealie Punkte 5918

R verfügt über eine Reihe von (undokumentierten) Komfortfunktionen zur Umrechnung von Faktoren:

  • as.character.factor
  • as.data.frame.factor
  • as.Date.factor
  • as.list.factor
  • as.vector.factor
  • ...

Aber ärgerlicherweise gibt es nichts, um die Faktor -> numerisch Umwandlung. In Erweiterung der Antwort von Joshua Ulrich würde ich vorschlagen, diese Lücke durch die Definition einer eigenen idiomatischen Funktion zu schließen:

as.double.factor <- function(x) {as.numeric(levels(x))[x]}

die Sie am Anfang Ihres Skripts speichern können, oder noch besser in Ihrem .Rprofile Datei.

14 Stimmen

Es gibt nichts, was die Umwandlung von Faktoren in Ganzzahlen (oder numerische Werte) behandeln könnte, da erwartet wird, dass as.integer(factor) gibt die zugrundeliegenden Integer-Codes zurück (wie im Abschnitt Beispiele unter ?factor ). Es ist wahrscheinlich in Ordnung, diese Funktion in Ihrer globalen Umgebung zu definieren, aber Sie könnten Probleme verursachen, wenn Sie sie tatsächlich als S3-Methode registrieren.

2 Stimmen

Das ist ein guter Punkt, und ich stimme zu: eine komplette Neudefinition der Faktor->Zahlen-Umwandlung wird wahrscheinlich vieles durcheinander bringen. Ich habe mich dabei ertappt, wie ich die umständliche factor->numeric Umwandlung eine Menge bevor ich feststellte, dass es sich um einen Mangel von R handelt: eine Komfortfunktion sollte verfügbar sein... Anrufen as.numeric.factor macht für mich Sinn, aber das ist Geschmackssache.

8 Stimmen

Wenn Sie sich dabei ertappen viel dann sollten Sie im Vorfeld etwas unternehmen, um dies ganz zu vermeiden.

48voto

Indi Punkte 1293

Hinweis: Diese besondere Antwort ist pas für die Umwandlung von numerisch bewerteten Faktoren in numerische Werte, sondern für die Umwandlung von kategorischen Faktoren in ihre entsprechenden Stufennummern.


Jede Antwort in diesem Beitrag führte bei mir nicht zu Ergebnissen, es wurden NAs generiert.

y2<-factor(c("A","B","C","D","A")); 
as.numeric(levels(y2))[y2] 
[1] NA NA NA NA NA Warning message: NAs introduced by coercion

Was bei mir funktioniert hat, ist Folgendes -

as.integer(y2)
# [1] 1 2 3 4 1

0 Stimmen

Sind Sie sicher, dass Sie einen Faktor hatten? Sehen Sie sich dieses Beispiel an. y<-factor(c("5","15","20","2")); unclass(y) %>% as.numeric Dies ergibt 4,1,3,2, nicht 5,15,20,2. Dies scheint eine falsche Information zu sein.

0 Stimmen

Ok, das ist ähnlich wie das, was ich heute versucht habe: - y2<-factor(c("A", "B", "C", "D", "A")); as.numeric(levels(y2))[y2] [1] NA NA NA NA NA Warnmeldung: NAs, die durch Zwang eingeführt wurden, während unclass(y2) %>% as.numeric mir die benötigten Ergebnisse lieferte.

0 Stimmen

Lassen Sie mich mein Szenario in meiner Antwort aktualisieren

43voto

Mehrad Mahmoudian Punkte 3120

Der einfachste Weg wäre die Verwendung von unfactor Funktion aus Paket varhandle die eine Faktor-Vektor oder sogar eine Datenrahmen :

unfactor(your_factor_variable)

Dieses Beispiel kann ein schneller Einstieg sein:

x <- rep(c("a", "b", "c"), 20)
y <- rep(c(1, 1, 0), 20)

class(x)  # -> "character"
class(y)  # -> "numeric"

x <- factor(x)
y <- factor(y)

class(x)  # -> "factor"
class(y)  # -> "factor"

library(varhandle)
x <- unfactor(x)
y <- unfactor(y)

class(x)  # -> "character"
class(y)  # -> "numeric"

Sie können sie auch für einen Datenrahmen verwenden. Zum Beispiel die iris Datensatz:

sapply(iris, class)
Sepal.Length  Sepal.Width Petal.Length  Petal.Width      Species
   "numeric"    "numeric"    "numeric"    "numeric"     "factor"
# load the package
library("varhandle")
# pass the iris to unfactor
tmp_iris <- unfactor(iris)
# check the classes of the columns
sapply(tmp_iris, class)
Sepal.Length  Sepal.Width Petal.Length  Petal.Width      Species
   "numeric"    "numeric"    "numeric"    "numeric"  "character"
# check if the last column is correctly converted
tmp_iris$Species
  [1] "setosa"     "setosa"     "setosa"     "setosa"     "setosa"    
  [6] "setosa"     "setosa"     "setosa"     "setosa"     "setosa"    
 [11] "setosa"     "setosa"     "setosa"     "setosa"     "setosa"    
 [16] "setosa"     "setosa"     "setosa"     "setosa"     "setosa"    
 [21] "setosa"     "setosa"     "setosa"     "setosa"     "setosa"    
 [26] "setosa"     "setosa"     "setosa"     "setosa"     "setosa"    
 [31] "setosa"     "setosa"     "setosa"     "setosa"     "setosa"
 [36] "setosa"     "setosa"     "setosa"     "setosa"     "setosa"
 [41] "setosa"     "setosa"     "setosa"     "setosa"     "setosa"
 [46] "setosa"     "setosa"     "setosa"     "setosa"     "setosa"
 [51] "versicolor" "versicolor" "versicolor" "versicolor" "versicolor"
 [56] "versicolor" "versicolor" "versicolor" "versicolor" "versicolor"
 [61] "versicolor" "versicolor" "versicolor" "versicolor" "versicolor"
 [66] "versicolor" "versicolor" "versicolor" "versicolor" "versicolor"
 [71] "versicolor" "versicolor" "versicolor" "versicolor" "versicolor"
 [76] "versicolor" "versicolor" "versicolor" "versicolor" "versicolor"
 [81] "versicolor" "versicolor" "versicolor" "versicolor" "versicolor"
 [86] "versicolor" "versicolor" "versicolor" "versicolor" "versicolor"
 [91] "versicolor" "versicolor" "versicolor" "versicolor" "versicolor"
 [96] "versicolor" "versicolor" "versicolor" "versicolor" "versicolor"
[101] "virginica"  "virginica"  "virginica"  "virginica"  "virginica"
[106] "virginica"  "virginica"  "virginica"  "virginica"  "virginica"
[111] "virginica"  "virginica"  "virginica"  "virginica"  "virginica"
[116] "virginica"  "virginica"  "virginica"  "virginica"  "virginica"
[121] "virginica"  "virginica"  "virginica"  "virginica"  "virginica"
[126] "virginica"  "virginica"  "virginica"  "virginica"  "virginica"
[131] "virginica"  "virginica"  "virginica"  "virginica"  "virginica"
[136] "virginica"  "virginica"  "virginica"  "virginica"  "virginica"
[141] "virginica"  "virginica"  "virginica"  "virginica"  "virginica"
[146] "virginica"  "virginica"  "virginica"  "virginica"  "virginica"

0 Stimmen

En unfactor Funktion konvertiert zuerst in den Datentyp Zeichen und konvertiert dann zurück in den Typ numerisch. Typ unfactor auf der Konsole und Sie können es in der Mitte der Funktion sehen. Daher gibt es nicht wirklich eine bessere Lösung als die, die der Fragesteller bereits hatte.

0 Stimmen

Abgesehen davon sind die Stufen eines Faktors ohnehin vom Charaktertyp, so dass bei diesem Ansatz nichts verloren geht.

0 Stimmen

En unfactor Funktion kümmert sich um Dinge, die nicht in numerische Werte umgewandelt werden können. Sehen Sie sich die Beispiele in help("unfactor")

13voto

djhurio Punkte 5272

Es ist möglich ばかり für den Fall, dass die Faktorbezeichnungen mit den Originalwerten übereinstimmen. Ich werde dies anhand eines Beispiels erläutern.

Angenommen, die Daten sind ein Vektor x :

x <- c(20, 10, 30, 20, 10, 40, 10, 40)

Jetzt werde ich einen Faktor mit vier Etiketten erstellen:

f <- factor(x, levels = c(10, 20, 30, 40), labels = c("A", "B", "C", "D"))

1) x ist vom Typ double, f ist vom Typ Ganzzahl. Dies ist der erste unvermeidliche Informationsverlust. Faktoren werden immer als ganze Zahlen gespeichert.

> typeof(x)
[1] "double"
> typeof(f)
[1] "integer"

2) Es ist nicht möglich, zu den ursprünglichen Werten (10, 20, 30, 40) zurückzukehren, wenn nur f verfügbar. Wir können sehen, dass f enthält nur die ganzzahligen Werte 1, 2, 3, 4 und zwei Attribute - die Liste der Bezeichnungen ("A", "B", "C", "D") und das Klassenattribut "factor". Mehr nicht.

> str(f)
 Factor w/ 4 levels "A","B","C","D": 2 1 3 2 1 4 1 4
> attributes(f)
$levels
[1] "A" "B" "C" "D"

$class
[1] "factor"

Um zu den ursprünglichen Werten zurückzukehren, müssen wir die Werte der bei der Erstellung des Faktors verwendeten Ebenen kennen. In diesem Fall c(10, 20, 30, 40) . Wenn wir die ursprünglichen Ebenen (in der richtigen Reihenfolge) kennen, können wir zu den ursprünglichen Werten zurückkehren.

> orig_levels <- c(10, 20, 30, 40)
> x1 <- orig_levels[f]
> all.equal(x, x1)
[1] TRUE

Und das funktioniert nur, wenn für alle möglichen Werte in den Originaldaten Bezeichnungen definiert wurden.

Wenn Sie also die Originalwerte benötigen, müssen Sie sie aufbewahren. Andernfalls besteht eine hohe Wahrscheinlichkeit, dass man nur über einen Faktor auf sie zurückgreifen kann.

5voto

davsjob Punkte 1712

Sie können verwenden hablar::convert wenn Sie einen Datenrahmen haben. Die Syntax ist einfach:

Stichprobe df

library(hablar)
library(dplyr)

df <- dplyr::tibble(a = as.factor(c("7", "3")),
                    b = as.factor(c("1.5", "6.3")))

Lösung

df %>% 
  convert(num(a, b))

gibt Ihnen:

# A tibble: 2 x 2
      a     b
  <dbl> <dbl>
1    7.  1.50
2    3.  6.30

Oder wenn Sie wollen, dass eine Spalte ganzzahlig und eine Spalte numerisch ist:

df %>% 
  convert(int(a),
          num(b))

führt zu:

# A tibble: 2 x 2
      a     b
  <int> <dbl>
1     7  1.50
2     3  6.30

0 Stimmen

Ein weiteres Paket nur für diesen einen Vorgang zu laden, ist jedoch nicht sparsam

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X