Tôi có data.frame chứa một số cột có tất cả các giá trị NA, làm cách nào để xóa chúng khỏi data.frame.
Tôi có thể sử dụng chức năng không
na.omit(...)
chỉ rõ một số luận cứ bổ sung?
Tôi có data.frame chứa một số cột có tất cả các giá trị NA, làm cách nào để xóa chúng khỏi data.frame.
Tôi có thể sử dụng chức năng không
na.omit(...)
chỉ rõ một số luận cứ bổ sung?
head(data)
? Bạn có muốn xóa các cột hoặc hàng tương ứng không?
Câu trả lời:
Một cách để làm điều đó:
df[, colSums(is.na(df)) != nrow(df)]
Nếu số NA trong một cột bằng số hàng thì nó phải hoàn toàn là NA.
Hoặc tương tự
df[colSums(!is.na(df)) > 0]
df[, colSums(is.na(df)) < nrow(df) * 0.5]
chỉ giữ các cột có ít nhất 50% ô trống.
df[, colSums(is.na(df)) != nrow(df) - 1]
kể từ khi đường chéo luôn là1
df %>% select_if(colSums(!is.na(.)) > 0)
Đây là một giải pháp dplyr:
df %>% select_if(~sum(!is.na(.)) > 0)
janitor::remove_empty_cols()
không được dùng nữa - sử dụngdf <- janitor::remove_empty(df, which = "cols")
Có vẻ như bạn muốn loại bỏ CHỈ các cột có TẤT CẢ NA
các cột, để lại các cột có một số hàng có NA
s. Tôi sẽ làm điều này (nhưng tôi chắc chắn có một cảnh báo vectorised hiệu quả:
#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
Nếu bạn thấy mình trong tình huống muốn xóa các cột có bất kỳ NA
giá trị nào, bạn có thể chỉ cần thay đổi all
lệnh ở trên thành any
.
NA
.
apply(is.na(df), 1, all)
mặc dù chỉ vì nó hơi gọn gàng hơn và is.na()
được sử dụng trên tất cả df
hơn là một hàng tại một thời điểm (hiển thị nhanh hơn một chút).
Một kịch bản trực quan: dplyr::select_if(~!all(is.na(.)))
. Theo nghĩa đen, nó chỉ giữ các cột không thiếu tất cả các phần tử. (để xóa tất cả các cột thiếu phần tử).
> 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
Vì hiệu suất thực sự quan trọng đối với tôi, tôi đã đánh giá tất cả các chức năng ở trên.
LƯU Ý: Dữ liệu từ bài đăng của @Simon O'Hanlon. Chỉ với kích thước 15000 thay vì 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
Các kết quả:
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")