Hier ist der Link meiner Daten.
Mein Ziel ist es, allen leeren Zellen "NA" zuzuweisen, unabhängig von kategorialen oder numerischen Werten. Ich benutze na.strings = "" . Es wird jedoch nicht allen leeren Zellen NA zugewiesen.
## reading the data
dat <- read.csv("data2.csv")
head(dat)
mon hr acc alc sex spd axles door reg cond1 drug1
1 8 21 No Control TRUE F 0 2 2 Physical Impairment (Eyes, Ear, Limb) A
2 7 20 No Control FALSE M 900 2 2 Inattentive D
3 3 9 No Control FALSE F 100 2 2 2004 Normal D
4 1 15 No Control FALSE M 0 2 2 Physical Impairment (Eyes, Ear, Limb) D
5 4 21 No Control FALSE 25 NA NA D
6 4 20 No Control NA F 30 2 4 Drinking Alcohol - Impaired D
inj1 PED_STATE st rac1
1 Fatal <NA> F <NA>
2 Moderate <NA> F <NA>
3 Moderate <NA> M <NA>
4 Complaint <NA> M <NA>
5 Complaint <NA> F <NA>
6 Moderate <NA> M <NA>
## using na.strings
dat2 <- read.csv("data2.csv", header=T, na.strings="")
head(dat2)
mon hr acc alc sex spd axles door reg cond1 drug1
1 8 21 No Control TRUE F 0 2 2 <NA> Physical Impairment (Eyes, Ear, Limb) A
2 7 20 No Control FALSE M 900 2 2 <NA> Inattentive D
3 3 9 No Control FALSE F 100 2 2 2004 Normal D
4 1 15 No Control FALSE M 0 2 2 <NA> Physical Impairment (Eyes, Ear, Limb) D
5 4 21 No Control FALSE 25 NA NA <NA> <NA> D
6 4 20 No Control NA F 30 2 4 <NA> Drinking Alcohol - Impaired D
inj1 PED_STATE st rac1
1 Fatal NA F NA
2 Moderate NA F NA
3 Moderate NA M NA
4 Complaint NA M NA
5 Complaint NA F NA
6 Moderate NA M NA
Antworten:
Ich gehe davon aus, dass Sie über Zeile 5 Spalte "Sex" sprechen. Es kann vorkommen, dass die Zelle in der Datei data2.csv ein Leerzeichen enthält und daher von R nicht als leer betrachtet wird.
Außerdem habe ich festgestellt, dass in Zeile 5 Spalten "Achsen" und "Tür" die aus data2.csv gelesenen Originalwerte die Zeichenfolge "NA" sind. Sie möchten diese wahrscheinlich auch als na.strings behandeln. Um dies zu tun,
dat2 <- read.csv("data2.csv", header=T, na.strings=c("","NA"))
BEARBEITEN:
Ich habe Ihre data2.csv heruntergeladen. Ja, in Zeile 5, Spalte "Geschlecht", ist ein Leerzeichen. Also du möchtest
na.strings=c(""," ","NA")
quelle
Sie können gsub verwenden, um mehrere Mutationen von Leerzeichen wie "" oder einem Leerzeichen als NA zu ersetzen:
data= data.frame(cats=c('', ' ', 'meow'), dogs=c("woof", " ", NA)) apply(data, 2, function(x) gsub("^$|^ $", NA, x))
quelle
gsub("^$", NA, trimws(x))
, um mehr als ein Leerzeichen innerhalb einer Zelle zu verarbeiten. Beachten Sie jedoch, dass beide Ansätze alle Spalten in Zeichenfolgen- / Zeichenvariablen konvertieren (falls nicht bereits geschehen).Eine augenfreundlichere Lösung
dplyr
wärerequire(dplyr) ## fake blank cells iris[1,1]="" ## define a helper function empty_as_na <- function(x){ if("factor" %in% class(x)) x <- as.character(x) ## since ifelse wont work with factors ifelse(as.character(x)!="", x, NA) } ## transform all columns iris %>% mutate_each(funs(empty_as_na))
Um die Korrektur nur auf eine Teilmenge von Spalten anzuwenden, können Sie Spalten von Interesse mithilfe der Spaltenanpassungssyntax von dplyr angeben. Beispiel:
mutate_each(funs(empty_as_na), matches("Width"), Species)
Wenn Ihre Tabelle Daten enthält, sollten Sie eine typsicherere Version von verwenden
ifelse
quelle
ifelse(x %in% c(""," ","NA"), NA, x)
.mutate_each
bietet mehr Flexibilität und ein wiederverwendbares Muster.dplyr
ist heutzutage in R-Workflows allgegenwärtig und wurde nur hinzugefügt, um die Antwort in sich geschlossen zu machen. Ich denke hierx!=""
ist richtig, da weder "" noch "NA" leer sind. Darüber hinaus schlägt die Antwort von @ sclarky für Datenrahmen mit Zahlen fehl, und @ Badoe's löst das Problem für vorhandene Datenrahmen nicht wirklich, sodass keine andere Antwort die Frage noch generisch zu beantworten scheint. Ich freue mich über bessere Lösungen.read.csv
um leere Zellen beim Lesen einer Tabelle aus einer Datei in NA umzuwandeln. Da der Titel der Frage jedoch "Ändern Sie die leeren Zellen in" NA "" lautet, sollte eine vollständige Antwort die Situation abdecken, in der sich ein data.frame bereits in der Umgebung befindet und der Benutzer leere Zellen entfernen möchte.df %>% mutate_all(funs(empty_as_na)) %>% summarize_all(funs(sum(is.na(.))))
Während dplyr in der Akzeptanz weit verbreitet ist oder nicht, erfreut es sich großer Beliebtheit bei einer großen Untergruppe von R-Benutzern, einschließlich mir. Vielen Dank für diese Lösung.Dies sollte den Trick tun
dat <- dat %>% mutate_all(na_if,"")
quelle
Ich bin kürzlich auf ähnliche Probleme gestoßen, und das hat bei mir funktioniert.
Wenn die Variable numerisch ist, sollte eine einfache Variable
df$Var[df$Var == ""] <- NA
ausreichen. Wenn die Variable jedoch ein Faktor ist, müssen Sie sie zuerst in das Zeichen konvertieren, dann die""
Zellen durch den gewünschten Wert ersetzen und sie wieder in den Faktor konvertieren. In diesem Fall, IhrerSex
Variablen, gehe ich davon aus, dass dies ein Faktor ist, und wenn Sie die leere Zelle ersetzen möchten, würde ich Folgendes tun:df$Var <- as.character(df$Var) df$Var[df$Var==""] <- NA df$Var <- as.factor(df$Var)
quelle
Meine Funktion berücksichtigt Faktor, Zeichenvektor und mögliche Attribute, wenn Sie zum Lesen externer Dateien einen Port oder ein Fremdpaket verwenden. Außerdem können verschiedene selbst definierte na.strings abgeglichen werden. Um alle Spalten zu transformieren, verwenden Sie einfach lappy:
df[] = lapply(df, blank2na, na.strings=c('','NA','na','N/A','n/a','NaN','nan'))
Weitere Kommentare:
#' Replaces blank-ish elements of a factor or character vector to NA #' @description Replaces blank-ish elements of a factor or character vector to NA #' @param x a vector of factor or character or any type #' @param na.strings case sensitive strings that will be coverted to NA. The function will do a trimws(x,'both') before conversion. If NULL, do only trimws, no conversion to NA. #' @return Returns a vector trimws (always for factor, character) and NA converted (if matching na.strings). Attributes will also be kept ('label','labels', 'value.labels'). #' @seealso \code{\link{ez.nan2na}} #' @export blank2na = function(x,na.strings=c('','.','NA','na','N/A','n/a','NaN','nan')) { if (is.factor(x)) { lab = attr(x, 'label', exact = T) labs1 <- attr(x, 'labels', exact = T) labs2 <- attr(x, 'value.labels', exact = T) # trimws will convert factor to character x = trimws(x,'both') if (! is.null(lab)) lab = trimws(lab,'both') if (! is.null(labs1)) labs1 = trimws(labs1,'both') if (! is.null(labs2)) labs2 = trimws(labs2,'both') if (!is.null(na.strings)) { # convert to NA x[x %in% na.strings] = NA # also remember to remove na.strings from value labels labs1 = labs1[! labs1 %in% na.strings] labs2 = labs2[! labs2 %in% na.strings] } # the levels will be reset here x = factor(x) if (! is.null(lab)) attr(x, 'label') <- lab if (! is.null(labs1)) attr(x, 'labels') <- labs1 if (! is.null(labs2)) attr(x, 'value.labels') <- labs2 } else if (is.character(x)) { lab = attr(x, 'label', exact = T) labs1 <- attr(x, 'labels', exact = T) labs2 <- attr(x, 'value.labels', exact = T) # trimws will convert factor to character x = trimws(x,'both') if (! is.null(lab)) lab = trimws(lab,'both') if (! is.null(labs1)) labs1 = trimws(labs1,'both') if (! is.null(labs2)) labs2 = trimws(labs2,'both') if (!is.null(na.strings)) { # convert to NA x[x %in% na.strings] = NA # also remember to remove na.strings from value labels labs1 = labs1[! labs1 %in% na.strings] labs2 = labs2[! labs2 %in% na.strings] } if (! is.null(lab)) attr(x, 'label') <- lab if (! is.null(labs1)) attr(x, 'labels') <- labs1 if (! is.null(labs2)) attr(x, 'value.labels') <- labs2 } else { x = x } return(x) }
quelle
Sie können auch
mutate_at
in verwendendplyr
dat <- dat %>% mutate_at(vars(colnames(.)), .funs = funs(ifelse(.=="", NA, as.character(.))))
Wählen Sie einzelne Spalten aus, die geändert werden sollen:
dat <- dat %>% mutate_at(vars(colnames(.)[names(.) %in% c("Age","Gender")]), .funs = funs(ifelse(.=="", NA, as.character(.))))
Ab (dplyr 0.8.0 oben) hat sich die Art und Weise, wie dies geschrieben werden soll, geändert. Bevor es war,
funs()
in.funs (funs(name = f(.))
. Stattdessen verwendenfuns
wir jetztlist (list(name = ~f(.)))
Beachten Sie, dass es auch eine viel einfachere Möglichkeit gibt, die Spaltennamen aufzulisten! (Sowohl der Name der Spalte als auch der Spaltenindex funktionieren)
dat <- dat %>% mutate_at(.vars = c("Age","Gender"), .funs = list(~ifelse(.=="", NA, as.character(.))))
quelle
Während viele der oben genannten Optionen gut funktionieren, fand ich das Erzwingen von Nicht-Zielvariablen
chr
problematisch. Die Verwendung vonifelse
undgrepl
innerhalblapply
löst diesen Off-Target-Effekt auf (in begrenzten Tests). Verwenden des regulären Ausdrucks von Slarky ingrepl
:set.seed(42) x1 <- sample(c("a","b"," ", "a a", NA), 10, TRUE) x2 <- sample(c(rnorm(length(x1),0, 1), NA), length(x1), TRUE) df <- data.frame(x1, x2, stringsAsFactors = FALSE)
Das Problem des Zwangs zur Charakterklasse:
df2 <- lapply(df, function(x) gsub("^$|^ $", NA, x)) lapply(df2, class)
$
x1
[1] "Zeichen"$ x2 [1] "Zeichen"
Auflösung unter Verwendung von ifelse:
df3 <- lapply(df, function(x) ifelse(grepl("^$|^ $", x)==TRUE, NA, x)) lapply(df3, class)
$
x1
[1] "Zeichen"$ x2 [1] "numerisch"
quelle
Ich vermute, jeder hat bereits eine Antwort, obwohl dplyr na_if () für den Fall, dass jemand auf der Suche ist, (aus meiner Sicht) die effizientere der genannten ist:
# Import CSV, convert all 'blank' cells to NA dat <- read.csv("data2.csv") %>% na_if("")
Hier ist ein zusätzlicher Ansatz, der die Funktion read_delim von readr nutzt. Ich habe gerade abgeholt (wahrscheinlich allgemein bekannt, aber ich werde hier für zukünftige Benutzer archivieren). Dies ist sehr einfach und vielseitiger als die oben genannten, da Sie alle Arten von leeren und NA-bezogenen Werten in Ihrer CSV-Datei erfassen können:
dat <- read_csv("data2.csv", na = c("", "NA", "N/A"))
Beachten Sie den Unterstrich in der Version von readr gegenüber Base R "." in read_csv.
Hoffentlich hilft das jemandem, der auf dem Posten wandert!
quelle
Könnten Sie nicht einfach verwenden
dat <- read.csv("data2.csv",na.strings=" ",header=TRUE)
Wenn Sie beim Einlesen der Daten alle Leerzeichen in NA konvertieren, müssen Sie zwischen Ihrem Angebot ein Leerzeichen einfügen
quelle
Für diejenigen, die sich über eine Lösung mit der Methode data.table wundern , ist hier eine, für die ich eine Funktion geschrieben habe, die auf meinem Github verfügbar ist:
library(devtools) source_url("https://github.com/YoannPa/Miscellaneous/blob/master/datatable_pattern_substitution.R?raw=TRUE") dt.sub(DT = dat2, pattern = "^$|^ $",replacement = NA) dat2
Die Funktion durchläuft jede Spalte, um festzustellen, welche Spalte Musterübereinstimmungen enthält. Dann
gsub()
wird nur auf Spalten angewendet, die Übereinstimmungen für das Muster enthalten"^$|^ $"
, um Übereinstimmungen durchNA
s zu ersetzen .Ich werde diese Funktion weiter verbessern, um sie schneller zu machen.
quelle
Rufen Sie das
dplyr
Paket auf, indem Sie escran
in r installierenlibrary(dplyr) (file)$(colname)<-sub("-",NA,file$colname)
Es werden alle leeren Zellen in einer bestimmten Spalte als NA konvertiert
Wenn die Spalte "-", "", 0 enthält, ändern Sie den Code entsprechend dem Typ der leeren Zelle
Wenn ich beispielsweise eine leere Zelle wie "" anstelle von "-" erhalte, verwenden Sie diesen Code:
(file)$(colname)<-sub("", NA, file$colname)
quelle
dplyr
nach dem Laden nicht verwendet und lässt sich nicht gut auf "alle Spalten" skalieren, nach denen OP sucht.