Wie kann ich Spalten mit mehr als einem NA-Schwellenwert löschen? oder in Prozent (sagen wir über 50%)?
Discipulus
2
@lovedynasty Am besten senden Sie eine separate Frage, vorausgesetzt, Sie haben Ihren Kommentar noch nicht veröffentlicht. Sie können jedoch immer so etwas tun, df[, colSums(is.na(df)) < nrow(df) * 0.5]dh nur Spalten mit mindestens 50% Nicht-Leerzeichen behalten.
MadScone
2
Leute, die mit einer Korrelationsmatrix arbeiten, müssen verwenden, df[, colSums(is.na(df)) != nrow(df) - 1]da die Diagonale immer ist1
Boern
9
Kann dies auch mit der Funktion select_if von dplyr (Version 0.5.0) verwenden. df %>% select_if(colSums(!is.na(.)) > 0)
Stefan Avey
@MadScone gibt mir einen Syntaxfehler bei "," für df [, colSums (is.na (df))! = Nrow (df)] und einen Syntaxfehler bei "!" in df [colSums (! is.na (df))> 0]. Vermisse ich etwas
Bei ~ 15.000 Zeilen und ~ 5.000 Spalten dauert dies wirklich ewig.
EngrStudent
@EngrStudent War es mit der Lösung der akzeptierten Antwort schneller?
Johnny
Es ist einige Jahre her. Ich erinnere mich nicht. DJV hat unten einen schönen Timing-Beitrag.
EngrStudent
24
Es sieht so aus, als ob Sie NUR Spalten mit ALLENNA s entfernen möchten , wobei Spalten mit einigen Zeilen mit s übrig bleiben NA. Ich würde dies tun (aber ich bin sicher, dass es eine effiziente vektorisierte Lösung gibt:
#set seed for reproducibility
set.seed <-103
df <- data.frame( id =1:10, nas = rep(NA,10), vals = sample( c(1:3,NA),10, repl =TRUE))
df# id nas vals# 1 1 NA NA# 2 2 NA 2# 3 3 NA 1# 4 4 NA 2# 5 5 NA 2# 6 6 NA 3# 7 7 NA 2# 8 8 NA 3# 9 9 NA 3# 10 10 NA 2#Use this command to remove columns that are entirely NA values, it will elave columns where only some vlaues are NA
df[,! apply( df ,2,function(x) all(is.na(x)))]# id vals# 1 1 NA# 2 2 2# 3 3 1# 4 4 2# 5 5 2# 6 6 3# 7 7 2# 8 8 3# 9 9 3# 10 10 2
Wenn Sie sich in einer Situation befinden, in der Sie Spalten mit beliebigen NAWerten entfernen möchten, können Sie den allobigen Befehl einfach in ändern any.
Der data.frame hat zwei Arten von Spalten: eine in whohc alle Werte sind Zahlen und die andere, in der alle Werte NA sind
Lorenzo Rigamonti
Das wird dann also funktionieren. Es werden nur Spalten entfernt, in denen ALLE Werte vorhanden sind NA.
Simon O'Hanlon
1
Gute Lösung. Ich würde es apply(is.na(df), 1, all)allerdings nur tun, weil es etwas ordentlicher is.na()ist und für alle dfund nicht nur für eine Reihe gleichzeitig verwendet wird (Show sei etwas schneller).
MadScone
@ MadScone guter Tipp - sieht ordentlicher aus. Sie sollten jedoch über Spalten und nicht über Zeilen hinweg anwenden.
Simon O'Hanlon
@ MadScone-Änderungen werden nach 5 Minuten für Kommentare gesperrt. Ich sollte mir keine Sorgen machen, es ist kein Problem !! :-)
janitor::remove_empty_cols()ist veraltet - Verwendungdf <- janitor::remove_empty(df, which = "cols")
André.B
19
Ein intuitives Skript : dplyr::select_if(~!all(is.na(.))). Es werden buchstäblich nur Spalten gespeichert, in denen nicht alle Elemente fehlen. (um Spalten zu löschen, bei denen alle Elemente fehlen).
> df <- data.frame( id =1:10, nas = rep(NA,10), vals = sample( c(1:3,NA),10, repl =TRUE))> df %>% glimpse()
Observations:10
Variables:3$ id <int>1,2,3,4,5,6,7,8,9,10$ nas <lgl>NA,NA,NA,NA,NA,NA,NA,NA,NA,NA$ vals <int>NA,1,1,NA,1,1,1,2,3,NA> df %>% select_if(~!all(is.na(.)))
id vals
11NA22133144NA5516617718829931010NA
Unit: microseconds
expr min lq mean median uq max neval cld
MadSconeF1 154.5178.35257.9396196.05219.255001.01000 a
MadSconeF2 180.4209.75281.2541226.40251.056322.11000 a
BradCannell 2579.42884.903330.37003059.453379.3033667.31000 d
SimonOHanlon 511.0565.00943.3089586.45623.65210338.41000 b
SiboJiang 2558.12853.053377.67023010.303310.0089718.01000 d
jsta 1544.81652.452031.50651706.051872.6511594.91000 c
akrun 93.8111.60139.9482121.90135.453851.21000 a
autoplot(mbm)
Manchmal ist die erste Iteration eine kompilierte JIT, daher hat sie sehr schlechte und nicht sehr charakteristische Zeiten. Ich finde es interessant, was die größere Stichprobe mit den richtigen Schwänzen der Verteilung macht. Das ist gute Arbeit.
EngrStudent
Ich habe es noch einmal ausgeführt und war mir nicht sicher, ob ich die Handlung geändert habe. In Bezug auf die Verteilung in der Tat. Ich sollte wahrscheinlich verschiedene Stichprobengrößen vergleichen, wenn ich Zeit habe.
DJV
1
Wenn Sie einen der Trends wie "akrun" qqplot ( ggplot2.tidyverse.org/reference/geom_qq.html ), dann wette ich, dass es einen Punkt gibt, der sich sehr von der Verteilung der anderen unterscheidet. Der Rest gibt an, wie lange es dauert, wenn Sie es wiederholt ausführen, aber das gibt an, was passiert, wenn Sie es einmal ausführen. Es gibt ein altes Sprichwort: Sie können 20 Jahre Erfahrung haben oder Sie können nur 20 Jahre Erfahrung 20 Mal haben.
EngrStudent
Sehr schön! Ich bin überrascht, dass sich mehrere Samples im extremen Schwanz befinden. Ich frage mich, warum diese so viel teurer sind. JIT kann 1 oder 2 sein, aber nicht 20. Bedingung? Interrupts? Andere? Nochmals vielen Dank für das Update.
EngrStudent
Gern geschehen, danke für die Gedanken. Weiß nicht, ich habe es tatsächlich "frei" laufen lassen.
head(data)
? Möchten Sie entsprechende Spalten oder Zeilen entfernen?Antworten:
Eine Möglichkeit, dies zu tun:
Wenn die Anzahl der NAs in einer Spalte der Anzahl der Zeilen entspricht, muss sie vollständig NA sein.
Oder ähnlich
quelle
df[, colSums(is.na(df)) < nrow(df) * 0.5]
dh nur Spalten mit mindestens 50% Nicht-Leerzeichen behalten.df[, colSums(is.na(df)) != nrow(df) - 1]
da die Diagonale immer ist1
df %>% select_if(colSums(!is.na(.)) > 0)
Hier ist eine dplyr-Lösung:
quelle
Es sieht so aus, als ob Sie NUR Spalten mit ALLEN
NA
s entfernen möchten , wobei Spalten mit einigen Zeilen mit s übrig bleibenNA
. Ich würde dies tun (aber ich bin sicher, dass es eine effiziente vektorisierte Lösung gibt:Wenn Sie sich in einer Situation befinden, in der Sie Spalten mit beliebigen
NA
Werten entfernen möchten, können Sie denall
obigen Befehl einfach in ändernany
.quelle
NA
.apply(is.na(df), 1, all)
allerdings nur tun, weil es etwas ordentlicheris.na()
ist und für alledf
und nicht nur für eine Reihe gleichzeitig verwendet wird (Show sei etwas schneller).Eine weitere Option ist das
janitor
Paket:https://github.com/sfirke/janitor
quelle
janitor::remove_empty_cols()
ist veraltet - Verwendungdf <- janitor::remove_empty(df, which = "cols")
Ein intuitives Skript :
dplyr::select_if(~!all(is.na(.)))
. Es werden buchstäblich nur Spalten gespeichert, in denen nicht alle Elemente fehlen. (um Spalten zu löschen, bei denen alle Elemente fehlen).quelle
Eine weitere Option mit
Filter
HINWEIS: Daten aus dem Beitrag von @Simon O'Hanlon.
quelle
Da die Leistung für mich sehr wichtig war, habe ich alle oben genannten Funktionen verglichen.
HINWEIS: Daten aus dem Beitrag von @Simon O'Hanlon. Nur mit Größe 15000 statt 10.
Ergebnisse:
quelle