Yanıtlar:
Bunu dene:
df <- df[,colSums(is.na(df))<nrow(df)]
Şu ana kadar sunulan iki yaklaşım, oluşturdukları büyük veri kümeleriyle (diğer bellek sorunlarının yanı sıra) is.na(df), aynı boyutta bir nesne olacak şekilde başarısız olmaktadır df.
İşte daha fazla bellek ve zamandan tasarruf sağlayan iki yaklaşım
Kullanarak bir yaklaşım Filter
Filter(function(x)!all(is.na(x)), df)
ve data.table kullanan bir yaklaşım (genel zaman ve bellek verimliliği için)
library(data.table)
DT <- as.data.table(df)
DT[,which(unlist(lapply(DT, function(x)!all(is.na(x))))),with=F]
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
data.frameYine de aynısını yapabilirsiniz . Burada gerçekten ihtiyacı olan hiçbir şey yok data.table. Anahtar, lapplytarafından yapılan tüm nesnenin kopyasını önleyen anahtardır is.na(df). İşaret etmek için +10.
bd1 <- bd[, unlist(lapply(bd, function(x), !all(is.na(x))))]
,sonra kaldırmak gerekir function(x)- örnek btw için teşekkürler
dplyrşimdi select_ifburada yardımcı olabilecek bir fiil var:
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
dplyrçözüm arıyor . Hayal kırıklığına uğradım. Teşekkürler!
Başka bir yol apply()işlevi kullanmak olabilir .
Data.frame'iniz varsa
df <- data.frame (var1 = c(1:7,NA),
var2 = c(1,2,1,3,4,NA,NA,9),
var3 = c(NA)
)
apply()hangi sütunların durumunuzu karşıladığını görmek için kullanabilirsiniz ve böylece Musa'nın cevabındakiyle aynı alt ayarı sadece bir applyyaklaşımla yapabilirsiniz.
> !apply (is.na(df), 2, all)
var1 var2 var3
TRUE TRUE FALSE
> df[, !apply(is.na(df), 2, all)]
var1 var2
1 1 1
2 2 2
3 3 1
4 4 3
5 5 4
6 6 NA
7 7 NA
8 NA 9
Umarım bu da yardımcı olabilir. Tek bir komut haline getirilebilirdi, ama okumayı iki komuta ayırarak daha kolay buldum. Aşağıdaki talimatla bir işlev yaptım ve yıldırım hızında çalıştım.
naColsRemoval = function (DataTable) {
na.cols = DataTable [ , .( which ( apply ( is.na ( .SD ) , 2 , all ) ) )]
DataTable [ , unlist (na.cols) := NULL , with = F]
}
.SD, doğrulamayı dilerseniz tablonun bir bölümü ile sınırlandırır, ancak tüm tabloyu aşağıdaki gibi alır
Kapıcı paketini kullanabilirsiniz remove_empty
library(janitor)
df %>%
remove_empty(c("rows", "cols")) #select either row or cols or both
Ayrıca, Başka bir dplyr yaklaşımı
library(dplyr)
df %>% select_if(~all(!is.na(.)))
VEYA
df %>% select_if(colSums(!is.na(.)) == nrow(df))
bu, yalnızca belirli sayıda eksik değere sahip sütunu hariç tutmak / tutmak istiyorsanız, örn.
df %>% select_if(colSums(!is.na(.))>500)