wake-up-neo.com

Wie kann man NA-Werte in einer Tabelle * für ausgewählte Spalten * ersetzen? data.frame, data.table

Es gibt viele Beiträge zum Ersetzen von NA-Werten. Mir ist bewusst, dass man NAs in der folgenden Tabelle/im folgenden Rahmen durch Folgendes ersetzen kann:

x[is.na(x)]<-0

Was aber, wenn ich es nur auf bestimmte Spalten beschränken möchte? Lassen Sie mich ein Beispiel zeigen.

Beginnen wir mit einem Datensatz.

set.seed(1234)
x <- data.frame(a=sample(c(1,2,NA), 10, replace=T),
                b=sample(c(1,2,NA), 10, replace=T), 
                c=sample(c(1:5,NA), 10, replace=T))

Was gibt:

    a  b  c
1   1 NA  2
2   2  2  2
3   2  1  1
4   2 NA  1
5  NA  1  2
6   2 NA  5
7   1  1  4
8   1  1 NA
9   2  1  5
10  2  1  1

Ok, ich möchte den Ersatz nur auf die Spalten 'a' und 'b' beschränken. Mein Versuch war:

x[is.na(x), 1:2]<-0

und:

x[is.na(x[1:2])]<-0

Was nicht funktioniert.

Mein data.table-Versuch, bei dem y<-data.table(x), funktionierte offensichtlich nie:

y[is.na(y[,list(a,b)]), ]

Ich möchte Spalten innerhalb des is.na-Arguments übergeben, aber das würde offensichtlich nicht funktionieren.

Ich möchte dies in einem data.frame und einer data.tabelle tun. Mein Endziel ist, das 1: 2 zu 0: 1 in 'a' und 'b' umzucodieren, während 'c' so bleibt, wie es ist, da es keine logische Variable ist. Ich habe eine Reihe von Kolumnen, deshalb möchte ich es nicht einzeln tun. Und ich würde gerne wissen, wie das geht.

Hast du irgendwelche Vorschläge?

64
jnam27

Du kannst tun:

x[, 1:2][is.na(x[, 1:2])] <- 0

oder besser (IMHO), verwenden Sie die Variablennamen:

x[c("a", "b")][is.na(x[c("a", "b")])] <- 0

In beiden Fällen kann 1:2 oder c("a", "b") durch einen vordefinierten Vektor ersetzt werden.

85
flodel

Dies funktioniert für Ihre data.table-Version:

for (col in c("a", "b")) y[is.na(get(col)), (col) := 0]

Wie David Arenburg weiter unten erläutert, können Sie alternativ set (Nebeneffekt - Sie können es entweder für data.frame oder data.table verwenden):

for (col in 1:2) set(x, which(is.na(x[[col]])), col, 0)
23
eddi

Dies ist jetzt in tidyr mit replace_na () trivial. Die Funktion scheint sowohl für data.tables als auch für data.frames zu funktionieren:

tidyr::replace_na(x, list(a=0, b=0))
11
Robert McDonald

Sie sind sich nicht sicher, ob dies genauer ist, aber diese Funktion wird auch NAs (oder einen beliebigen Wert) in ausgewählten Spalten einer data.table suchen und ersetzen lassen:

update.mat <- function(dt, cols, criteria) {
  require(data.table)
  x <- as.data.frame(which(criteria==TRUE, arr.ind = TRUE))
  y <- as.matrix(subset(x, x$col %in% which((names(dt) %in% cols), arr.ind = TRUE)))
  y
}

Um es anzuwenden:

y[update.mat(y, c("a", "b"), is.na(y))] <- 0

Die Funktion erstellt eine Matrix der ausgewählten Spalten und Zeilen (Zellkoordinaten), die die Eingabekriterien erfüllen (in diesem Fall is.na == TRUE).

1
Amy M

Aufbauend auf der Antwort von @Robert McDonald's tidyr::replace_na() gibt es hier einige dplyr -Optionen, mit denen gesteuert werden kann, welche Spalten durch die NA ersetzt werden:

library(tidyverse)

# by column type:
x %>%
  mutate_if(is.numeric, ~replace_na(., 0))

# select columns defined in vars(col1, col2, ...):
x %>%
  mutate_at(vars(a, b, c), ~replace_na(., 0))

# all columns:
x %>%
  mutate_all(~replace_na(., 0))
0
sbha

Für eine bestimmte Spalte gibt es eine Alternative mit sapply

DF <- data.frame(A = letters[1:5],
             B = letters[6:10],
             C = c(2, 5, NA, 8, NA))

DF_NEW <- sapply(seq(1, nrow(DF)),
                    function(i) ifelse(is.na(DF[i,3]) ==
                                       TRUE,
                                       0,
                                       DF[i,3]))

DF[,3] <- DF_NEW
DF
0
Rafa
We can solve it in data.table way with tidyr::repalce_na function and lapply
library(data.table)
library(tidyr)
setDT(df)
df[,c("a","b","c"):=lapply(.SD,function(x) replace_na(x,0)),.SDcols=c("a","b","c")]

In this way,we can also solve paste cloumns with NA string.First, we replace_na(x,""),then we can use stringr::str_c to combine columns!
0
young Chen