Удалить столбцы из фрейма данных, где все значения NA



У меня возникли проблемы с фрейм данных, и я не мог решить эту проблему сам:

Элемент dataframe имеет произвольную свойства в виде столбцов и каждую строку - один набор данных.



Вопрос в том:

Как это избавиться от Столбцов, где к все строки значение NA?

588   6  

6 ответов:

попробуйте это:

df <- df[,colSums(is.na(df))<nrow(df)]

два подхода, предлагаемые до сих пор терпят неудачу с большими наборами данных, поскольку (среди других проблем с памятью) они создают is.na(df), который будет объект того же размера, что и df.

вот два подхода, которые являются более эффективной памяти и времени

подход с использованием Filter

Filter(function(x)!all(is.na(x)), df)

и подход с использованием данных.таблица (для общего времени и эффективности памяти)

library(data.table)
DT <- as.data.table(df)
DT[,which(unlist(lapply(DT, function(x)!all(is.na(x))))),with=F]

примеры использования больших данных (30 столбцов, 1e6 строки)

big_data <- replicate(10, data.frame(rep(NA, 1e6), sample(c(1:8,NA),1e6,T), sample(250,1e6,T)),simplify=F)
bd <- do.call(data.frame,big_data)
names(bd) <- paste0('X',seq_len(30))
DT <- as.data.table(bd)

system.time({df1 <- bd[,colSums(is.na(bd) < nrow(bd))]})
# error -- can't allocate vector of size ...
system.time({df2 <- bd[, !apply(is.na(bd), 2, all)]})
# error -- can't allocate vector of size ...
system.time({df3 <- Filter(function(x)!all(is.na(x)), bd)})
## user  system elapsed 
## 0.26    0.03    0.29 
system.time({DT1 <- DT[,which(unlist(lapply(DT, function(x)!all(is.na(x))))),with=F]})
## user  system elapsed 
## 0.14    0.03    0.18 

другой способ - использовать

dplyr теперь select_if глагол, который может быть полезным здесь:

library(dplyr)
temp <- data.frame(x = 1:5, y = c(1,2,NA,4, 5), z = rep(NA, 5))
not_all_na <- function(x) any(!is.na(x))
not_any_na <- function(x) all(!is.na(x))

> temp
  x  y  z
1 1  1 NA
2 2  2 NA
3 3 NA NA
4 4  4 NA
5 5  5 NA

> temp %>% select_if(not_all_na)
  x  y
1 1  1
2 2  2
3 3 NA
4 4  4
5 5  5

> temp %>% select_if(not_any_na)
  x
1 1
2 2
3 3
4 4
5 5
df[sapply(df, function(x) all(is.na(x)))] <- NULL

Я надеюсь, что это также может помочь. Это можно было бы сделать в одну команду, но мне было легче читать, разделив его на две команды. Я сделал функцию со следующей инструкцией и работал молниеносно.

naColsRemoval = function (DataTable) { na.cols = DataTable [ , .( which ( apply ( is.na ( .SD ) , 2 , all ) ) )] DataTable [ , unlist (na.cols) := NULL , with = F] }

. SD позволит ограничить проверку частью таблицы, если вы хотите, но он будет принимать всю таблицу как

Comments

    Ничего не найдено.