Ich habe einen Datenrahmen mit a factor
. Wenn ich eine Teilmenge dieses Datenrahmens mit subset
oder einer anderen Indizierungsfunktion erstelle , wird ein neuer Datenrahmen erstellt. Die factor
Variable behält jedoch alle ursprünglichen Ebenen bei, auch wenn sie im neuen Datenrahmen nicht vorhanden sind.
Dies führt zu Problemen beim Erstellen von Facetten oder beim Verwenden von Funktionen, die auf Faktorstufen beruhen.
Was ist der prägnanteste Weg, um Ebenen aus einem Faktor im neuen Datenrahmen zu entfernen?
Hier ist ein Beispiel:
df <- data.frame(letters=letters[1:5],
numbers=seq(1:5))
levels(df$letters)
## [1] "a" "b" "c" "d" "e"
subdf <- subset(df, numbers <= 3)
## letters numbers
## 1 a 1
## 2 b 2
## 3 c 3
# all levels are still there!
levels(subdf$letters)
## [1] "a" "b" "c" "d" "e"
mydf <- droplevels(mydf)
Datenrahmen in eine Liste, weshalb die von Roman Luštrik und Tommy O'Dell unten vorgeschlagene Lösung vorzuziehen ist.Seit R Version 2.12 gibt es eine
droplevels()
Funktion.quelle
factor()
besteht darin, dass der ursprüngliche Datenrahmen nicht geändert oder ein neuer persistenter Datenrahmen erstellt werden muss. Ich kanndroplevels
einen untergeordneten Datenrahmen umschließen und ihn als Datenargument für eine Gitterfunktion verwenden, und Gruppen werden korrekt behandelt.Wenn Sie dieses Verhalten nicht möchten, verwenden Sie keine Faktoren, sondern stattdessen Zeichenvektoren. Ich denke, das ist sinnvoller, als die Dinge danach zu reparieren. Versuchen Sie Folgendes, bevor Sie Ihre Daten mit
read.table
oder ladenread.csv
:Der Nachteil ist, dass Sie sich auf die alphabetische Reihenfolge beschränken. (Nachbestellung ist dein Freund für Grundstücke)
quelle
Es ist ein bekanntes Problem, und eine mögliche Lösung finden Sie
drop.levels()
im gdata- Paket, in dem Ihr Beispiel angezeigt wirdEs gibt auch die
dropUnusedLevels
Funktion im Hmisc- Paket. Es funktioniert jedoch nur durch Ändern des Teilmengenoperators[
und ist hier nicht anwendbar.Als Konsequenz ist ein direkter Ansatz auf Spaltenbasis einfach
as.factor(as.character(data))
:quelle
reorder
Parameter derdrop.levels
Funktion ist erwähnenswert: Wenn Sie die ursprüngliche Reihenfolge Ihrer Faktoren beibehalten müssen, verwenden Sie sie mitFALSE
Wert.Ein anderer Weg, dasselbe zu tun, aber mit
dplyr
Bearbeiten:
Funktioniert auch! Danke an agenis
quelle
Der Vollständigkeit halber gibt es jetzt auch
fct_drop
dasforcats
Paket http://forcats.tidyverse.org/reference/fct_drop.html .Es unterscheidet sich von
droplevels
der Art und Weise, wie es behandelt wirdNA
:quelle
Hier ist ein anderer Weg, der meiner Meinung nach dem
factor(..)
Ansatz entspricht:quelle
`[.factor`
Methode gibt, die eindrop
Argument hat, und Sie haben dies 2009 gepostet ...Das ist widerlich. So mache ich es normalerweise, um das Laden anderer Pakete zu vermeiden:
was bringt dich:
Beachten Sie, dass die neuen Ebenen alles ersetzen, was ihren Index in den alten Ebenen belegt (subdf $ Buchstaben), also so etwas wie:
wird nicht funktionieren.
Dies ist natürlich nicht ideal, wenn Sie viele Level haben, aber für einige ist es schnell und einfach.
quelle
Wenn Sie sich den
droplevels
Methodencode in der R-Quelle ansehen , sehen Sie, dass erfactor
funktioniert. Das heißt, Sie können die Spalte grundsätzlich mitfactor
Funktion neu erstellen .Unterhalb der data.table-Methode können Ebenen aus allen Faktorspalten gelöscht werden.
quelle
data.table
Weg wäre so etwas wiefor (j in names(DT)[sapply(DT, is.factor)]) set(DT, j = j, value = factor(DT[[j]]))
[.data.table
nur einmalHier ist ein Weg, das zu tun
quelle
Ich habe dazu Dienstprogrammfunktionen geschrieben. Jetzt, wo ich über gdatas drop.levels Bescheid weiß, sieht es ziemlich ähnlich aus. Hier sind sie (von hier ):
quelle
Sehr interessanter Thread, mir hat besonders die Idee gefallen, die Unterauswahl einfach wieder zu faktorisieren. Ich hatte vorher ein ähnliches Problem und bin einfach zum Charakter und dann zurück zum Faktor konvertiert.
quelle
factor(as.chracter(...))
funktioniert, aber nur weniger effizient und prägnant alsfactor(...)
. Scheint streng schlechter als die anderen Antworten.Leider scheint factor () bei Verwendung von rxDataStep von RevoScaleR nicht zu funktionieren. Ich mache es in zwei Schritten: 1) In Zeichen konvertieren und in einem temporären externen Datenrahmen (.xdf) speichern. 2) Zurück zum Faktor konvertieren und im endgültigen externen Datenrahmen speichern. Dadurch werden nicht verwendete Faktorstufen eliminiert, ohne dass alle Daten in den Speicher geladen werden müssen.
quelle
Habe die meisten Beispiele hier ausprobiert, wenn in meinem Fall nicht alle, aber keine zu funktionieren scheinen. Nachdem ich einige Zeit gekämpft habe, habe ich versucht, as.character () für die Faktorspalte zu verwenden, um sie in eine Spalte mit Zeichenfolgen zu ändern, die anscheinend einwandfrei funktioniert.
Nicht sicher für Leistungsprobleme.
quelle