Ich habe einen data.frame, der einige Spalten mit allen NA-Werten enthält. Wie kann ich sie aus dem data.frame löschen?
Kann ich die Funktion nutzen?
na.omit(...)
einige zusätzliche Argumente angeben?
Ich habe einen data.frame, der einige Spalten mit allen NA-Werten enthält. Wie kann ich sie aus dem data.frame löschen?
Kann ich die Funktion nutzen?
na.omit(...)
einige zusätzliche Argumente angeben?
head(data)
? Möchten Sie entsprechende Spalten oder Zeilen entfernen?
Antworten:
Eine Möglichkeit, dies zu tun:
df[, colSums(is.na(df)) != nrow(df)]
Wenn die Anzahl der NAs in einer Spalte der Anzahl der Zeilen entspricht, muss sie vollständig NA sein.
Oder ähnlich
df[colSums(!is.na(df)) > 0]
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:
df %>% select_if(~sum(!is.na(.)) > 0)
Es sieht so aus, als ob Sie NUR Spalten mit ALLEN NA
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 NA
Werten entfernen möchten, können Sie den all
obigen Befehl einfach in ändern any
.
NA
.
apply(is.na(df), 1, all)
allerdings nur tun, weil es etwas ordentlicher is.na()
ist und für alle df
und nicht nur für eine Reihe gleichzeitig verwendet wird (Show sei etwas schneller).
Eine weitere Option ist das janitor
Paket:
df <- remove_empty_cols(df)
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).
> 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
1 1 NA
2 2 1
3 3 1
4 4 NA
5 5 1
6 6 1
7 7 1
8 8 2
9 9 3
10 10 NA
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.
library(tidyverse)
library(microbenchmark)
set.seed(123)
df <- data.frame(id = 1:15000,
nas = rep(NA, 15000),
vals = sample(c(1:3, NA), 15000,
repl = TRUE))
df
MadSconeF1 <- function(x) x[, colSums(is.na(x)) != nrow(x)]
MadSconeF2 <- function(x) x[colSums(!is.na(x)) > 0]
BradCannell <- function(x) x %>% select_if(~sum(!is.na(.)) > 0)
SimonOHanlon <- function(x) x[ , !apply(x, 2 ,function(y) all(is.na(y)))]
jsta <- function(x) janitor::remove_empty(x)
SiboJiang <- function(x) x %>% dplyr::select_if(~!all(is.na(.)))
akrun <- function(x) Filter(function(y) !all(is.na(y)), x)
mbm <- microbenchmark(
"MadSconeF1" = {MadSconeF1(df)},
"MadSconeF2" = {MadSconeF2(df)},
"BradCannell" = {BradCannell(df)},
"SimonOHanlon" = {SimonOHanlon(df)},
"SiboJiang" = {SiboJiang(df)},
"jsta" = {jsta(df)},
"akrun" = {akrun(df)},
times = 1000)
mbm
Ergebnisse:
Unit: microseconds
expr min lq mean median uq max neval cld
MadSconeF1 154.5 178.35 257.9396 196.05 219.25 5001.0 1000 a
MadSconeF2 180.4 209.75 281.2541 226.40 251.05 6322.1 1000 a
BradCannell 2579.4 2884.90 3330.3700 3059.45 3379.30 33667.3 1000 d
SimonOHanlon 511.0 565.00 943.3089 586.45 623.65 210338.4 1000 b
SiboJiang 2558.1 2853.05 3377.6702 3010.30 3310.00 89718.0 1000 d
jsta 1544.8 1652.45 2031.5065 1706.05 1872.65 11594.9 1000 c
akrun 93.8 111.60 139.9482 121.90 135.45 3851.2 1000 a
autoplot(mbm)
mbm %>%
tbl_df() %>%
ggplot(aes(sample = time)) +
stat_qq() +
stat_qq_line() +
facet_wrap(~expr, scales = "free")