답변:
지금까지 제공된 두 가지 접근 방식은 (다른 메모리 문제 중) 생성 is.na(df)
하는 것과 같은 대용량 데이터 세트에서는 실패 합니다.df
.
더 많은 메모리와 시간 효율적인 두 가지 접근법이 있습니다.
사용하는 접근법 Filter
Filter(function(x)!all(is.na(x)), df)
data.table을 사용하는 접근법 (일반적인 시간과 메모리 효율성을 위해)
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.frame
그래도 같은 작업을 수행 할 수 있습니다. 여기 정말로 필요한 것은 없습니다 data.table
. 열쇠는 lapply
이며, 전체 객체의 복사를 피합니다 is.na(df)
. 지적 +10
bd1 <- bd[, unlist(lapply(bd, function(x), !all(is.na(x))))]
,
후 후 제거해야한다고 생각 function(x)
-예 btw에 대한 감사
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
dplyr
해결책을 찾아 여기에 왔습니다 . 실망하지 않았습니다. 감사!
다른 방법은 apply()
기능 을 사용하는 것입니다.
data.frame이있는 경우
df <- data.frame (var1 = c(1:7,NA),
var2 = c(1,2,1,3,4,NA,NA,9),
var3 = c(NA)
)
그러면 apply()
어떤 열이 조건을 충족하는지 확인할 수 있으므로 apply
접근 방식 만으로 Musa의 답변에서와 동일한 하위 설정을 수행 할 수 있습니다 .
> !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
이것이 도움이되기를 바랍니다. 단일 명령으로 만들 수는 있지만 두 명령으로 나누면 더 읽기 쉽습니다. 나는 다음과 같은 명령으로 기능하고 번개를 빨리 일했습니다.
naColsRemoval = function (DataTable) {
na.cols = DataTable [ , .( which ( apply ( is.na ( .SD ) , 2 , all ) ) )]
DataTable [ , unlist (na.cols) := NULL , with = F]
}
.SD는 원하는 경우 확인을 테이블의 일부로 제한 할 수 있지만 전체 테이블을 다음과 같이 사용합니다.
관리인 패키지를 사용할 수 있습니다 remove_empty
library(janitor)
df %>%
remove_empty(c("rows", "cols")) #select either row or cols or both
또한, 또 다른 dplyr 접근법
library(dplyr)
df %>% select_if(~all(!is.na(.)))
또는
df %>% select_if(colSums(!is.na(.)) == nrow(df))
이것은 특정 개수의 결 측값이있는 열만 제외 / 유지하려는 경우에도 유용합니다. 예 :
df %>% select_if(colSums(!is.na(.))>500)