Wie ersetze ich NA-Werte in einem R-Datenrahmen durch Nullen?

728

Ich habe einen Datenrahmen und einige Spalten haben NAWerte.

Wie ersetze ich diese NAWerte durch Nullen?

Renato Dinhani
quelle
13
kleine Modifikation von stackoverflow.com/questions/7279089/… (die ich durch die Suche nach "[r] ersetze NA durch Null" gefunden habe) ...
Ben Bolker
25
d [is.na (d)] <- 0
Psychonomie

Antworten:

879

Siehe meinen Kommentar in @ gsk3 Antwort. Ein einfaches Beispiel:

> m <- matrix(sample(c(NA, 1:10), 100, replace = TRUE), 10)
> d <- as.data.frame(m)
   V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
1   4  3 NA  3  7  6  6 10  6   5
2   9  8  9  5 10 NA  2  1  7   2
3   1  1  6  3  6 NA  1  4  1   6
4  NA  4 NA  7 10  2 NA  4  1   8
5   1  2  4 NA  2  6  2  6  7   4
6  NA  3 NA NA 10  2  1 10  8   4
7   4  4  9 10  9  8  9  4 10  NA
8   5  8  3  2  1  4  5  9  4   7
9   3  9 10  1  9  9 10  5  3   3
10  4  2  2  5 NA  9  7  2  5   5

> d[is.na(d)] <- 0

> d
   V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
1   4  3  0  3  7  6  6 10  6   5
2   9  8  9  5 10  0  2  1  7   2
3   1  1  6  3  6  0  1  4  1   6
4   0  4  0  7 10  2  0  4  1   8
5   1  2  4  0  2  6  2  6  7   4
6   0  3  0  0 10  2  1 10  8   4
7   4  4  9 10  9  8  9  4 10   0
8   5  8  3  2  1  4  5  9  4   7
9   3  9 10  1  9  9 10  5  3   3
10  4  2  2  5  0  9  7  2  5   5

Es besteht keine Notwendigkeit, sich zu bewerben apply. =)

BEARBEITEN

Sie sollten sich auch das normPaket ansehen . Es hat viele nette Funktionen für die Analyse fehlender Daten. =)

aL3xa
quelle
2
Ich habe diesen Code bereits gestern ausprobiert, bevor Sie ihn veröffentlicht haben, und er hat nicht funktioniert. Weil ich die Frage gestellt habe. Aber ich habe es versucht und perfekt gearbeitet. Ich glaube, ich habe etwas falsch gemacht.
Renato Dinhani
12
@ RenatoDinhaniConceição: Wenn Sie bereits etwas ausprobiert haben, ist es hilfreich, diese Informationen zu teilen, wenn Sie die Frage stellen. Es hilft, das Problem einzugrenzen.
Aaron verließ Stack Overflow
2
d [is.na (d)] <- 0 ergibt für mich keinen Sinn. Es scheint rückwärts? Wie verarbeitet R diese Aussage?
user798719
13
@ user798719 - "<-" ist Rs Zuweisungsoperator und kann wie folgt gelesen werden: Machen Sie etwas auf der rechten Seite und weisen Sie es dann dem Ort / Namen auf der linken Seite zu. In diesem Fall "tun" wir eigentlich nichts - machen nur Nullen. Die linke Seite sagt: Schauen Sie sich das d-Objekt an, finden Sie innerhalb des d-Objekts (die eckigen Klammern) alle Elemente, die TRUE zurückgeben (is.na (d) gibt für jedes Element eine Logik zurück). Sobald sie gefunden wurden, ersetzen Sie sie ("weisen Sie sie zu") durch den Wert 0. Dadurch bleiben alle Nicht-NAs unverändert und ersetzen nur diejenigen, die fehlen.
Twitch_City
3
Und ... wenn Sie einen Datenrahmen haben und den Ersatz nur auf bestimmte Nurmer-Vektoren anwenden möchten (lassen Sie beispielsweise ... Zeichenfolgen mit NA):df[19:28][is.na(df[19:28])] <- 0
jtdoud
299

Die mit dplyr hybridisierten Optionen sind jetzt etwa 30% schneller als die Neuzuweisung der Base R-Teilmenge. Auf einem 100M-Datenpunkt mutate_all(~replace(., is.na(.), 0))läuft der Datenrahmen eine halbe Sekunde schneller als die Basis-R- d[is.na(d)] <- 0Option. Was man konkret vermeiden möchte, ist die Verwendung eines ifelse()oder eines if_else(). (Die vollständige 600-Studienanalyse dauerte mehr als 4,5 Stunden, hauptsächlich aufgrund der Einbeziehung dieser Ansätze.) Die vollständigen Ergebnisse finden Sie in den folgenden Benchmark-Analysen.

Wenn Sie mit massivem Datenrahmen zu kämpfen hat , data.tableist die schnellste Möglichkeit , alle: 40% schneller als der Standard - Base - R - Ansatz. Außerdem werden die vorhandenen Daten geändert, sodass Sie effektiv mit fast doppelt so vielen Daten gleichzeitig arbeiten können.


Eine Zusammenfassung anderer hilfreicher Tidyverse-Ersatzansätze

Standortlich:

  • Index mutate_at(c(5:10), ~replace(., is.na(.), 0))
  • direkte Referenz mutate_at(vars(var5:var10), ~replace(., is.na(.), 0))
  • Übereinstimmung mutate_at(vars(contains("1")), ~replace(., is.na(.), 0))
    • oder anstelle von contains(), versuchen Sie ends_with(),starts_with()
  • Muster Match mutate_at(vars(matches("\\d{2}")), ~replace(., is.na(.), 0))

Bedingt:
(Nur einen Typ ändern und andere Typen in Ruhe lassen.)

  • ganze Zahlen mutate_if(is.integer, ~replace(., is.na(.), 0))
  • Zahlen mutate_if(is.numeric, ~replace(., is.na(.), 0))
  • Saiten mutate_if(is.character, ~replace(., is.na(.), 0))

Die vollständige Analyse -

Aktualisiert für dplyr 0.8.0: Funktionen verwenden ~Symbole im Purrr-Format : Ersetzen veralteter funs()Argumente.

Getestete Ansätze:

# Base R: 
baseR.sbst.rssgn   <- function(x) { x[is.na(x)] <- 0; x }
baseR.replace      <- function(x) { replace(x, is.na(x), 0) }
baseR.for          <- function(x) { for(j in 1:ncol(x))
    x[[j]][is.na(x[[j]])] = 0 }

# tidyverse
## dplyr
dplyr_if_else      <- function(x) { mutate_all(x, ~if_else(is.na(.), 0, .)) }
dplyr_coalesce     <- function(x) { mutate_all(x, ~coalesce(., 0)) }

## tidyr
tidyr_replace_na   <- function(x) { replace_na(x, as.list(setNames(rep(0, 10), as.list(c(paste0("var", 1:10)))))) }

## hybrid 
hybrd.ifelse     <- function(x) { mutate_all(x, ~ifelse(is.na(.), 0, .)) }
hybrd.replace_na <- function(x) { mutate_all(x, ~replace_na(., 0)) }
hybrd.replace    <- function(x) { mutate_all(x, ~replace(., is.na(.), 0)) }
hybrd.rplc_at.idx<- function(x) { mutate_at(x, c(1:10), ~replace(., is.na(.), 0)) }
hybrd.rplc_at.nse<- function(x) { mutate_at(x, vars(var1:var10), ~replace(., is.na(.), 0)) }
hybrd.rplc_at.stw<- function(x) { mutate_at(x, vars(starts_with("var")), ~replace(., is.na(.), 0)) }
hybrd.rplc_at.ctn<- function(x) { mutate_at(x, vars(contains("var")), ~replace(., is.na(.), 0)) }
hybrd.rplc_at.mtc<- function(x) { mutate_at(x, vars(matches("\\d+")), ~replace(., is.na(.), 0)) }
hybrd.rplc_if    <- function(x) { mutate_if(x, is.numeric, ~replace(., is.na(.), 0)) }

# data.table   
library(data.table)
DT.for.set.nms   <- function(x) { for (j in names(x))
    set(x,which(is.na(x[[j]])),j,0) }
DT.for.set.sqln  <- function(x) { for (j in seq_len(ncol(x)))
    set(x,which(is.na(x[[j]])),j,0) }
DT.nafill        <- function(x) { nafill(df, fill=0)}
DT.setnafill     <- function(x) { setnafill(df, fill=0)}

Der Code für diese Analyse:

library(microbenchmark)
# 20% NA filled dataframe of 10 Million rows and 10 columns
set.seed(42) # to recreate the exact dataframe
dfN <- as.data.frame(matrix(sample(c(NA, as.numeric(1:4)), 1e7*10, replace = TRUE),
                            dimnames = list(NULL, paste0("var", 1:10)), 
                            ncol = 10))
# Running 600 trials with each replacement method 
# (the functions are excecuted locally - so that the original dataframe remains unmodified in all cases)
perf_results <- microbenchmark(
    hybrid.ifelse    = hybrid.ifelse(copy(dfN)),
    dplyr_if_else    = dplyr_if_else(copy(dfN)),
    hybrd.replace_na = hybrd.replace_na(copy(dfN)),
    baseR.sbst.rssgn = baseR.sbst.rssgn(copy(dfN)),
    baseR.replace    = baseR.replace(copy(dfN)),
    dplyr_coalesce   = dplyr_coalesce(copy(dfN)),
    tidyr_replace_na = tidyr_replace_na(copy(dfN)),
    hybrd.replace    = hybrd.replace(copy(dfN)),
    hybrd.rplc_at.ctn= hybrd.rplc_at.ctn(copy(dfN)),
    hybrd.rplc_at.nse= hybrd.rplc_at.nse(copy(dfN)),
    baseR.for        = baseR.for(copy(dfN)),
    hybrd.rplc_at.idx= hybrd.rplc_at.idx(copy(dfN)),
    DT.for.set.nms   = DT.for.set.nms(copy(dfN)),
    DT.for.set.sqln  = DT.for.set.sqln(copy(dfN)),
    times = 600L
)

Zusammenfassung der Ergebnisse

> print(perf_results)
Unit: milliseconds
              expr       min        lq     mean   median       uq      max neval
      hybrd.ifelse 6171.0439 6339.7046 6425.221 6407.397 6496.992 7052.851   600
     dplyr_if_else 3737.4954 3877.0983 3953.857 3946.024 4023.301 4539.428   600
  hybrd.replace_na 1497.8653 1706.1119 1748.464 1745.282 1789.804 2127.166   600
  baseR.sbst.rssgn 1480.5098 1686.1581 1730.006 1728.477 1772.951 2010.215   600
     baseR.replace 1457.4016 1681.5583 1725.481 1722.069 1766.916 2089.627   600
    dplyr_coalesce 1227.6150 1483.3520 1524.245 1519.454 1561.488 1996.859   600
  tidyr_replace_na 1248.3292 1473.1707 1521.889 1520.108 1570.382 1995.768   600
     hybrd.replace  913.1865 1197.3133 1233.336 1238.747 1276.141 1438.646   600
 hybrd.rplc_at.ctn  916.9339 1192.9885 1224.733 1227.628 1268.644 1466.085   600
 hybrd.rplc_at.nse  919.0270 1191.0541 1228.749 1228.635 1275.103 2882.040   600
         baseR.for  869.3169 1180.8311 1216.958 1224.407 1264.737 1459.726   600
 hybrd.rplc_at.idx  839.8915 1189.7465 1223.326 1228.329 1266.375 1565.794   600
    DT.for.set.nms  761.6086  915.8166 1015.457 1001.772 1106.315 1363.044   600
   DT.for.set.sqln  787.3535  918.8733 1017.812 1002.042 1122.474 1321.860   600

Boxplot der Ergebnisse

ggplot(perf_results, aes(x=expr, y=time/10^9)) +
    geom_boxplot() +
    xlab('Expression') +
    ylab('Elapsed Time (Seconds)') +
    scale_y_continuous(breaks = seq(0,7,1)) +
    coord_flip()

Boxplot-Vergleich der verstrichenen Zeit

Farbcodiertes Streudiagramm der Versuche (mit y-Achse auf einer logarithmischen Skala)

qplot(y=time/10^9, data=perf_results, colour=expr) + 
    labs(y = "log10 Scaled Elapsed Time per Trial (secs)", x = "Trial Number") +
    coord_cartesian(ylim = c(0.75, 7.5)) +
    scale_y_log10(breaks=c(0.75, 0.875, 1, 1.25, 1.5, 1.75, seq(2, 7.5)))

Streudiagramm aller Testzeiten

Ein Hinweis zu den anderen Leistungsträgern

Wenn die Datensätze größer werden, hat sich Tidyr 's replace_nahistorisch nach vorne zurückgezogen. Mit der aktuellen Sammlung von 100 Millionen Datenpunkten, die durchlaufen werden müssen, ist die Leistung fast genauso gut wie bei einer Base R For Loop. Ich bin gespannt, was bei unterschiedlich großen Datenrahmen passiert.

Weitere Beispiele für die Varianten mutateund summarize _atund _allfinden Sie hier: https://rdrr.io/cran/dplyr/man/summarise_all.html Außerdem habe ich hier hilfreiche Demonstrationen und Sammlungen von Beispielen gefunden: https: //blog.exploratory. io / dplyr-0-5-is-awesome-heres-why-be095fd4eb8a

Zuschreibungen und Wertschätzungen

Mit besonderem Dank an:

  • Tyler Rinker und Akrun für die Demonstration von Mikrobenchmark.
  • alexis_laz für seine Arbeit, um mir zu helfen, die Verwendung local()und (auch mit Franks geduldiger Hilfe) die Rolle zu verstehen, die stiller Zwang bei der Beschleunigung vieler dieser Ansätze spielt.
  • ArthurYip für den Poke, um die neuere coalesce()Funktion hinzuzufügen und die Analyse zu aktualisieren.
  • Gregor für den Anstoß, die data.tableFunktionen gut genug herauszufinden, um sie endlich in die Aufstellung aufzunehmen.
  • Basis R Für Schleife: alexis_laz
  • data.table For Loops: Matt_Dowle
  • Roman für die Erklärung, was is.numeric()wirklich testet.

(Natürlich greifen Sie bitte zu ihnen und geben Sie ihnen auch Stimmen, wenn Sie diese Ansätze nützlich finden.)

Hinweis zu meiner Verwendung von Numerics: Wenn Sie ein reines Integer-Dataset haben, werden alle Ihre Funktionen schneller ausgeführt. Bitte beachten Sie alexiz_laz Arbeit für weitere Informationen. IRL, ich kann mich nicht erinnern, auf einen Datensatz gestoßen zu sein, der mehr als 10-15% Ganzzahlen enthält. Daher führe ich diese Tests für vollständig numerische Datenrahmen aus.

Verwendete Hardware 3,9 GHz CPU mit 24 GB RAM

leerssej
quelle
2
@Frank - Vielen Dank, dass Sie diese Diskrepanz gefunden haben. Die Referenzen werden alle bereinigt und die Ergebnisse wurden vollständig auf einer einzelnen Maschine erneut ausgeführt und erneut veröffentlicht.
Leerssej
OK danke. Auch ich denke df1[j][is.na(df1[j])] = 0ist falsch, sollte seindf1[[j]][is.na(df1[[j]])] = 0
Frank
Oh, jetzt sehe ich, dass Sie es zweimal geschrieben haben, in jedem Benchmark anders. Wie auch immer, es forLp_Sbstscheint nicht so, als ob jemand darüber nachdenken sollte, sich ihm zu nähernforLp_smplfSbst
Frank
1
@UweBlock - tolle Frage: Es hat mir erlaubt, die Teilmengen-Linkszuweisungsoperation mit allen Funktionen durchzuführen, die an genau demselben Datenrahmen arbeiten. Da ich das Lokale um diese Funktion wickeln musste, wickelte ich es im Namen der Wissenschaft [Ein Job, Sie hatten einen Job!] Um alle, so dass das Spielfeld eindeutig gleich war. Weitere Informationen finden Sie hier: stackoverflow.com/questions/41604711/… Ich hatte die ziemlich langwierige vorherige Antwort gekürzt - aber dieser Teil der Diskussion wäre gut, um ihn wieder hinzuzufügen. Vielen Dank!
Leerssej
1
@ArthurYip - Ich habe die coalesce()Option hinzugefügt und immer wieder ausgeführt. Vielen Dank für den Anstoß zum Update.
Leerssej
128

Für einen einzelnen Vektor:

x <- c(1,2,NA,4,5)
x[is.na(x)] <- 0

Machen Sie für einen data.frame eine Funktion aus dem oben genannten und dann applyzu den Spalten.

Bitte geben Sie beim nächsten Mal ein reproduzierbares Beispiel an, wie hier beschrieben:

Wie macht man ein gutes reproduzierbares R-Beispiel?

Ari B. Friedman
quelle
18
is.naist eine generische Funktion und verfügt über Methoden für Objekte der data.frameKlasse. also wird dieser auch auf data.frames funktionieren !
aL3xa
3
Als ich methods(is.na)zum ersten Mal rannte , war ich wie was?!? . Ich liebe es, wenn so etwas passiert! =)
aL3xa
9
Angenommen, Sie haben einen Datenrahmen mit dem Namen df anstelle eines einzelnen Vektors und möchten nur fehlende Beobachtungen in einer einzelnen Spalte mit dem Namen X3 ersetzen. Sie können dies mit dieser Zeile tun: df $ X3 [is.na (df $ X3)] <- 0
Mark Miller
8
Angenommen, Sie möchten NA nur in den Spalten 4-6 eines Datenrahmens mit dem Namen my.df. durch 0 ersetzen. Sie können verwenden: my.df [, 4: 6] [is.na (my.df [, 4: 6])] <- 0
Mark Miller
Wie kommt es, dass Sie 'x' an is.na (x) übergeben? Gibt es eine Möglichkeit zu erkennen, welche Bibliotheksroutinen in R vektorisiert sind?
uh_big_mike_boi
73

dplyr Beispiel:

library(dplyr)

df1 <- df1 %>%
    mutate(myCol1 = if_else(is.na(myCol1), 0, myCol1))

Hinweis: Dies funktioniert für jede ausgewählte Spalte. Wenn dies für alle Spalten erforderlich ist , lesen Sie die Antwort von @reidjax mit mutate_each .

ianmunoz
quelle
57

Wenn wir versuchen, NAs beim Exportieren zu ersetzen , beispielsweise beim Schreiben in csv, können wir Folgendes verwenden:

  write.csv(data, "data.csv", na = "0")
Frau Voltys
quelle
47

Ich weiß, dass die Frage bereits beantwortet ist, aber auf diese Weise könnte es für einige nützlicher sein:

Definieren Sie diese Funktion:

na.zero <- function (x) {
    x[is.na(x)] <- 0
    return(x)
}

Wann immer Sie NAs in einem Vektor in Nullen konvertieren müssen, können Sie Folgendes tun:

na.zero(some.vector)
krishan404
quelle
22

Mit dplyr0.5.0 können Sie coalesceFunktionen verwenden, die auf einfache Weise in die %>%Pipeline integriert werden können coalesce(vec, 0). Dies ersetzt alle NAs vecdurch 0:

Angenommen, wir haben einen Datenrahmen mit NAs:

library(dplyr)
df <- data.frame(v = c(1, 2, 3, NA, 5, 6, 8))

df
#    v
# 1  1
# 2  2
# 3  3
# 4 NA
# 5  5
# 6  6
# 7  8

df %>% mutate(v = coalesce(v, 0))
#   v
# 1 1
# 2 2
# 3 3
# 4 0
# 5 5
# 6 6
# 7 8
Psidom
quelle
Ich habe Coalesce getestet und es funktioniert ungefähr genauso wie das Ersetzen. Der Koaleszenzbefehl ist der bisher einfachste!
Arthur Yip
Es wäre nützlich, wenn Sie erläutern würden, wie dies auf alle Spalten mit mehr als 2 Spalten angewendet werden kann.
Jangorecki
21

Allgemeineren Ansatz der Verwendung replace()in Matrix oder Vektor ersetzen NAzu0

Zum Beispiel:

> x <- c(1,2,NA,NA,1,1)
> x1 <- replace(x,is.na(x),0)
> x1
[1] 1 2 0 0 1 1

Dies ist auch eine Alternative zur Verwendung ifelse()indplyr

df = data.frame(col = c(1,2,NA,NA,1,1))
df <- df %>%
   mutate(col = replace(col,is.na(col),0))
Charleslmh
quelle
1
Meine Spalte war ein Faktor, also musste ich meinen Ersatzwert hinzufügenlevels(A$x) <- append(levels(A$x), "notAnswered") A$x <- replace(A$x,which(is.na(A$x)),"notAnswered")
Climbs_lika_Spyder
1
whichwird hier nicht benötigt, können Sie verwenden x1 <- replace(x,is.na(x),1).
lmo
Ich habe viele in diesem Thread vorgeschlagene Möglichkeiten ausprobiert, um NAsie 0in nur einer bestimmten Spalte in einem großen Datenrahmen zu ersetzen , und diese Funktion replace()hat am effektivsten und gleichzeitig am einfachsten funktioniert .
Duc
19

Es ist auch möglich zu verwenden tidyr::replace_na.

    library(tidyr)
    df <- df %>% mutate_all(funs(replace_na(.,0)))
Sasha
quelle
9

Ein weiteres Beispiel für das imputeTS- Paket:

library(imputeTS)
na.replace(yourDataframe, 0)
stats0007
quelle
9

Wenn Sie NAs in Faktorvariablen ersetzen möchten, kann dies hilfreich sein:

n <- length(levels(data.vector))+1

data.vector <- as.numeric(data.vector)
data.vector[is.na(data.vector)] <- n
data.vector <- as.factor(data.vector)
levels(data.vector) <- c("level1","level2",...,"leveln", "NAlevel") 

Es transformiert einen Faktorvektor in einen numerischen Vektor und fügt eine weitere künstliche numerische Faktorebene hinzu, die dann mit einer zusätzlichen "NA-Ebene" Ihrer Wahl in einen Faktorvektor zurücktransformiert wird.

user6075957
quelle
8

Hätte den Beitrag von @ ianmunoz kommentiert, aber ich habe nicht genug Ruf. Sie können kombinieren dplyr‚s mutate_eachund replaceBetreuung von nehmen , NAum 0Ersatz. Verwenden des Datenrahmens aus der Antwort von @ aL3xa ...

> m <- matrix(sample(c(NA, 1:10), 100, replace = TRUE), 10)
> d <- as.data.frame(m)
> d

    V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
1   4  8  1  9  6  9 NA  8  9   8
2   8  3  6  8  2  1 NA NA  6   3
3   6  6  3 NA  2 NA NA  5  7   7
4  10  6  1  1  7  9  1 10  3  10
5  10  6  7 10 10  3  2  5  4   6
6   2  4  1  5  7 NA NA  8  4   4
7   7  2  3  1  4 10 NA  8  7   7
8   9  5  8 10  5  3  5  8  3   2
9   9  1  8  7  6  5 NA NA  6   7
10  6 10  8  7  1  1  2  2  5   7

> d %>% mutate_each( funs_( interp( ~replace(., is.na(.),0) ) ) )

    V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
1   4  8  1  9  6  9  0  8  9   8
2   8  3  6  8  2  1  0  0  6   3
3   6  6  3  0  2  0  0  5  7   7
4  10  6  1  1  7  9  1 10  3  10
5  10  6  7 10 10  3  2  5  4   6
6   2  4  1  5  7  0  0  8  4   4
7   7  2  3  1  4 10  0  8  7   7
8   9  5  8 10  5  3  5  8  3   2
9   9  1  8  7  6  5  0  0  6   7
10  6 10  8  7  1  1  2  2  5   7

Wir verwenden hier die Standardbewertung (SE), weshalb wir den Unterstrich " funs_." Wir verwenden auch lazyeval's interp/ ~und die .Referenzen "alles, mit dem wir arbeiten", dh den Datenrahmen. Jetzt gibt es Nullen!

reidjax
quelle
4

Sie können verwenden replace()

Zum Beispiel:

> x <- c(-1,0,1,0,NA,0,1,1)
> x1 <- replace(x,5,1)
> x1
[1] -1  0  1  0  1  0  1  1

> x1 <- replace(x,5,mean(x,na.rm=T))
> x1
[1] -1.00  0.00  1.00  0.00  0.29  0.00 1.00  1.00
Zahra
quelle
6
Richtig, aber nur praktisch, wenn Sie den Index von NAs in Ihrem Vektor kennen. Es ist gut für kleine Vektoren wie in Ihrem Beispiel.
Dardisco
4
@dardisco x1 <- replace(x,is.na(x),1)funktioniert ohne explizite Auflistung der Indexwerte.
lmo
4

Eine weitere dplyrPipe-kompatible Option mit einer tidyrMethode replace_na, die für mehrere Spalten funktioniert:

require(dplyr)
require(tidyr)

m <- matrix(sample(c(NA, 1:10), 100, replace = TRUE), 10)
d <- as.data.frame(m)

myList <- setNames(lapply(vector("list", ncol(d)), function(x) x <- 0), names(d))

df <- d %>% replace_na(myList)

Sie können sich leicht auf z. B. numerische Spalten beschränken:

d$str <- c("string", NA)

myList <- myList[sapply(d, is.numeric)]

df <- d %>% replace_na(myList)
Antti
quelle
4

Die dafür vorgesehene Funktion ( nafill/ setnafill) ist in der aktuellen data.tableVersion enthalten

install.packages("data.table", repos="https://Rdatatable.gitlab.io/data.table")
library(data.table)
ans_df = nafill(df, fill=0)
setnafill(df, fill=0) # this one updates in-place
jangorecki
quelle
Für diejenigen, die abstimmen, geben Sie bitte auch Feedback, damit meine Antwort verbessert werden kann.
Jangorecki
3

Diese einfache Funktion aus Datacamp könnte helfen:

replace_missings <- function(x, replacement) {
  is_miss <- is.na(x)
  x[is_miss] <- replacement

  message(sum(is_miss), " missings replaced by the value ", replacement)
  x
}

Dann

replace_missings(df, replacement = 0)
Fábio
quelle
3

Eine einfache Möglichkeit , es zu schreiben , ist mit if_navon hablar:

library(dplyr)
library(hablar)

df <- tibble(a = c(1, 2, 3, NA, 5, 6, 8))

df %>% 
  mutate(a = if_na(a, 0))

was zurückgibt:

      a
  <dbl>
1     1
2     2
3     3
4     0
5     5
6     6
7     8
Davsjob
quelle
2

So ersetzen Sie alle NAs in einem Datenrahmen:

df %>% replace(is.na(.), 0)

Oliver Oliver
quelle
Dies ist keine neue Lösung
Jogo
1

Wenn Sie nach dem Ändern der NAs in einer bestimmten Spalte in diesem Fall einen neuen Namen zuweisen möchten, können Sie dies auch tun

my.data.frame$the.new.column.name <- ifelse(is.na(my.data.frame$V3),0,1)
Seyma Kalay
quelle