Ich habe einen Datenrahmen mit einigen numerischen Spalten. Einige Zeilen haben einen Wert von 0, der in der statistischen Analyse als Null betrachtet werden sollte. Was ist der schnellste Weg, um den gesamten 0-Wert in R durch NULL zu ersetzen?
Ich habe einen Datenrahmen mit einigen numerischen Spalten. Einige Zeilen haben einen Wert von 0, der in der statistischen Analyse als Null betrachtet werden sollte. Was ist der schnellste Weg, um den gesamten 0-Wert in R durch NULL zu ersetzen?
Antworten:
Ersetzen aller Nullen durch NA:
df[df == 0] <- NA
Erläuterung
1. Es ist nicht das, durch NULL
das Sie Nullen ersetzen möchten. Wie es in heißt ?'NULL'
,
NULL repräsentiert das Nullobjekt in R.
Das ist einzigartig und kann als das uninformativste und leerste Objekt angesehen werden. 1 Dann wird es nicht so überraschend, dass
data.frame(x = c(1, NULL, 2))
# x
# 1 1
# 2 2
Das heißt, R reserviert keinen Platz für dieses Nullobjekt. 2 In der Zwischenzeit ?'NA'
sehen wir das
NA ist eine logische Konstante der Länge 1, die einen Indikator für fehlende Werte enthält. NA kann zu jedem anderen Vektortyp außer roh gezwungen werden.
Wichtig ist, dass NA
es die Länge 1 hat, damit R etwas Platz dafür reserviert. Z.B,
data.frame(x = c(1, NA, 2))
# x
# 1 1
# 2 NA
# 3 2
Außerdem erfordert die Datenrahmenstruktur, dass alle Spalten die gleiche Anzahl von Elementen aufweisen, damit keine "Löcher" (dh NULL
Werte) vorhanden sein können.
Jetzt können Sie Nullen durch NULL
in einem Datenrahmen ersetzen, indem Sie alle Zeilen, die mindestens eine Null enthalten, vollständig entfernen. Bei der Verwendung von , zum Beispiel var
, cov
oder cor
, ist , dass tatsächlich äquivalent ersten Nullen mit dem Ersetzen NA
und Einstellen des Wertes des use
als "complete.obs"
. In der Regel ist dies jedoch unbefriedigend, da dies zu einem zusätzlichen Informationsverlust führt.
2. Anstatt eine Art Schleife auszuführen, verwende ich in der Lösung die df == 0
Vektorisierung. df == 0
gibt (versuchen Sie es) eine Matrix der gleichen Größe wie df
mit den Einträgen TRUE
und zurück FALSE
. Außerdem dürfen wir diese Matrix an die Teilmenge übergeben [...]
(siehe ?'['
). Obwohl das Ergebnis von df[df == 0]
vollkommen intuitiv ist, mag es seltsam erscheinen, df[df == 0] <- NA
den gewünschten Effekt zu erzielen. Der Zuweisungsoperator <-
ist in der Tat nicht immer so intelligent und funktioniert auf diese Weise nicht mit einigen anderen Objekten, sondern mit Datenrahmen. siehe ?'<-'
.
1 Die leere Menge in der Mengenlehre fühlt sich irgendwie verwandt an.
2 Eine weitere Ähnlichkeit mit der Mengenlehre: Die leere Menge ist eine Teilmenge jeder Menge, aber wir reservieren keinen Platz dafür.
Angenommen, Ihr data.frame ist eine Mischung aus verschiedenen Datentypen und nicht alle Spalten müssen geändert werden.
Um nur die Spalten 12 bis 18 (von insgesamt 21) zu ändern, tun Sie dies einfach
df[, 12:18][df[, 12:18] == 0] <- NA
Ein alternativer Weg ohne die [<-
Funktion:
Ein Beispieldatenrahmen dat
(schamlos aus der Antwort von @ Chase kopiert):
dat
x y
1 0 2
2 1 2
3 1 1
4 2 1
5 0 0
Nullen ersetzt werden kann NA
durch die is.na<-
Funktion:
is.na(dat) <- !dat
dat
x y
1 NA 2
2 1 2
3 1 1
4 2 1
5 NA NA
#Sample data
set.seed(1)
dat <- data.frame(x = sample(0:2, 5, TRUE), y = sample(0:2, 5, TRUE))
#-----
x y
1 0 2
2 1 2
3 1 1
4 2 1
5 0 0
#replace zeros with NA
dat[dat==0] <- NA
#-----
x y
1 NA 2
2 1 2
3 1 1
4 2 1
5 NA NA
Da jemand nach der Data.Table-Version gefragt hat und die angegebene data.frame-Lösung nicht mit data.table funktioniert, biete ich die folgende Lösung an.
Verwenden Sie grundsätzlich den :=
Operator ->DT[x == 0, x := NA]
library("data.table")
status = as.data.table(occupationalStatus)
head(status, 10)
origin destination N
1: 1 1 50
2: 2 1 16
3: 3 1 12
4: 4 1 11
5: 5 1 2
6: 6 1 12
7: 7 1 0
8: 8 1 0
9: 1 2 19
10: 2 2 40
status[N == 0, N := NA]
head(status, 10)
origin destination N
1: 1 1 50
2: 2 1 16
3: 3 1 12
4: 4 1 11
5: 5 1 2
6: 6 1 12
7: 7 1 NA
8: 8 1 NA
9: 1 2 19
10: 2 2 40
Sie können ersetzen 0
mit NA
nur in numerischen Feldern (dh Dinge wie Faktoren ausschließlich), aber es funktioniert auf einer Säule- für -Spalte - Basis:
col[col == 0 & is.numeric(col)] <- NA
Mit einer Funktion können Sie dies auf Ihren gesamten Datenrahmen anwenden:
changetoNA <- function(colnum,df) {
col <- df[,colnum]
if (is.numeric(col)) { #edit: verifying column is numeric
col[col == -1 & is.numeric(col)] <- NA
}
return(col)
}
df <- data.frame(sapply(1:5, changetoNA, df))
Obwohl Sie die 1:5
durch die Anzahl der Spalten in Ihrem Datenrahmen oder durch ersetzen könnten 1:ncol(df)
.
1:5
mit 1:ncol(df)
am Ende. Ich wollte die Gleichung nicht zu komplex oder schwer lesbar machen.
1:5
zu ändernden Spaltennummern ändern. 12:15
Wenn Sie jedoch bestätigen möchten, dass nur numerische Spalten betroffen sind, setzen Sie die zweite Zeile der Funktion in eine if-Anweisung wie folgt : if (is.numeric(col)) { col[col == -1 & is.numeric(col)] <- NA }
.