Vervang alle 0-waarden door NA

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 NULLwaarmee 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 NAlengte 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 NULLin een dataframe in de zin van het volledig verwijderen van alle rijen met ten minste één nul. Als u bijvoorbeeld var, covof corgebruikt, komt dat overeen met het eerst vervangen van nullen door NAen het instellen van de waarde van useals "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 == 0vectorisatie. df == 0retourneert (probeer het) een matrix van dezelfde grootte als df, met de items TRUEen 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] <- NAde 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 NAdoor 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 0vervangen door NAalleen 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:5zou 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

Other episodes