Ik heb een dataframe met enkele numerieke kolommen. Sommige rijen hebben een 0-waarde die in statistische analyse als nul moet worden beschouwd. Wat is de snelste manier om alle 0-waarden te vervangen door NULL in R?
Antwoord 1, autoriteit 100%
Alle nullen vervangen door NA:
df[df == 0] <- NA
Uitleg
1.Het is niet NULL
waarmee u nullen wilt vervangen. Zoals het staat in ?'NULL'
,
NULL vertegenwoordigt het null-object in R
wat uniek is en, denk ik, gezien kan worden als het meest informatieve en lege object.1Dan wordt het niet zo verwonderlijk dat
data.frame(x = c(1, NULL, 2))
# x
# 1 1
# 2 2
Dat wil zeggen, R reserveert geen ruimte voor dit null-object.2Ondertussen, kijkend naar ?'NA'
zien we dat
NA is een logische constante met lengte 1 die een ontbrekende waarde bevat
indicator. NA kan worden gedwongen tot elk ander vectortype behalve raw.
Belangrijk is dat NA
lengte 1 heeft, zodat R er wat ruimte voor reserveert. Bijvoorbeeld,
data.frame(x = c(1, NA, 2))
# x
# 1 1
# 2 NA
# 3 2
Bovendien vereist de dataframestructuur dat alle kolommen hetzelfde aantal elementen hebben, zodat er geen “gaten” kunnen zijn (d.w.z. NULL
-waarden).
Je zou nu nullen kunnen vervangen door NULL
in een dataframe in de zin van het volledig verwijderen van alle rijen met ten minste één nul. Als u bijvoorbeeld var
, cov
of cor
gebruikt, komt dat overeen met het eerst vervangen van nullen door NA
en het instellen van de waarde van use
als "complete.obs"
. Meestal is dit echter onbevredigend omdat het leidt tot extra informatieverlies.
2.In plaats van een soort lus uit te voeren, gebruik ik in de oplossing df == 0
vectorisatie. df == 0
retourneert (probeer het) een matrix van dezelfde grootte als df
, met de items TRUE
en FALSE
. Verder mogen we deze matrix ook doorgeven aan de subset [...]
(zie ?'['
). Ten slotte, hoewel het resultaat van df[df == 0]
volkomen intuïtief is, kan het vreemd lijken dat df[df == 0] <- NA
de gewenste effect. De toewijzingsoperator <-
is inderdaad niet altijd even slim en werkt niet op deze manier met sommige andere objecten, maar wel met dataframes; zie ?'<-'
.
1De lege verzameling in de verzamelingenleer voelt op de een of andere manier verwant aan.
2Nog een overeenkomst met de verzamelingenleer: de lege verzameling is een deelverzameling van elke verzameling, maar we reserveren er geen ruimte voor.
Antwoord 2, autoriteit 15%
Laat me aannemen dat uw data.frame een mix is van verschillende datatypes en dat niet alle kolommen moeten worden aangepast.
om alleen kolommen 12 t/m 18 (van de in totaal 21) te wijzigen, doet u dit gewoon
df[, 12:18][df[, 12:18] == 0] <- NA
Antwoord 3, autoriteit 12%
dplyr::na_if()
is een optie:
library(dplyr)
df <- data_frame(col1 = c(1, 2, 3, 0),
col2 = c(0, 2, 3, 4),
col3 = c(1, 0, 3, 0),
col4 = c('a', 'b', 'c', 'd'))
na_if(df, 0)
# A tibble: 4 x 4
col1 col2 col3 col4
<dbl> <dbl> <dbl> <chr>
1 1 NA 1 a
2 2 2 NA b
3 3 3 3 c
4 NA 4 NA d
Antwoord 4, autoriteit 8%
Een alternatieve manier zonder de functie [<-
:
Een voorbeeldgegevensframe dat
(schaamteloos gekopieerd van het antwoord van @Chase):
dat
x y
1 0 2
2 1 2
3 1 1
4 2 1
5 0 0
Nullen kunnen worden vervangen door NA
door de functie is.na<-
:
is.na(dat) <- !dat
dat
x y
1 NA 2
2 1 2
3 1 1
4 2 1
5 NA NA
Antwoord 5, autoriteit 5%
#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
Antwoord 6, autoriteit 4%
Omdat iemand om de Data.Table-versie hiervan heeft gevraagd en omdat de gegeven data.frame-oplossing niet werkt met data.table, bied ik de onderstaande oplossing.
Kortom, gebruik de 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
Antwoord 7, autoriteit 2%
Als iemand hier via google aankomt op zoek naar het tegenovergestelde(d.w.z. hoe alle NA’s in een data.frame door 0 te vervangen), is het antwoord
df[is.na(df)] <- 0
OF
Dplyr / netjesvers gebruiken
library(dplyr)
mtcars %>% replace(is.na(.), 0)
Antwoord 8
U kunt 0
vervangen door NA
alleen in numerieke velden (dwz met uitzondering van zaken als factoren), maar het werkt per kolom:
col[col == 0 & is.numeric(col)] <- NA
Met een functie kun je dit toepassen op je hele dataframe:
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))
Hoewel je de 1:5
zou kunnen vervangen door het aantal kolommen in je dataframe, of door 1:ncol(df)
.
Antwoord 9
Als je net als ik bent en hier bent beland terwijl je je afvroeg hoe je ALLE waarden in een dataframe kunt vervangen door NA, dan is het gewoon:
df[,] <- NA