当您拥有数据集时,通常您希望看到数据集中至少有一个NA(或缺失值)的行的比例。
在R中,我所做的是以下内容:
TR = apply(my_data,1,anyNA)
sum(TR)/length(TR)
但我发现如果我的数据集有100万行,则需要一些时间。我想知道在R中是否有最快的方法来实现这个目标?
答案 0 :(得分:1)
在开始之前,请注意这里的代码都不是我的。我只是对评论中的代码着迷,并想知道哪一个真的表现得最好。
我怀疑有些时候正忙于将数据帧转换为apply
和rowSums
的矩阵,所以我也完成了矩阵上的大多数解决方案来说明通过在数据框上运行这些解决方案来应用惩罚。
# Make a data frame of 10,000 rows and set random values to NA
library(dplyr)
set.seed(13)
MT <- mtcars[sample(1:nrow(mtcars), size = 10000, replace = TRUE), ]
MT <- lapply(MT,
function(x) { x[sample(1:length(x), size = 100)] <- NA; x }) %>%
bind_cols()
MT_mat <- as.matrix(MT)
library(microbenchmark)
microbenchmark(
apply(MT,1,anyNA),
apply(MT_mat,1,anyNA), # apply on a matrix
row_sum = rowSums(is.na(MT)) > 0,
row_sum_mat = rowSums(is.na(MT_mat)), # rowSums on a matrix
reduce = Reduce('|', lapply(MT, is.na)) ,
complete_case = !complete.cases(MT),
complete_case_mat = !complete.cases(MT_mat) # complete.cases on a matrix
)
Unit: microseconds
expr min lq mean median uq max neval cld
apply(MT, 1, anyNA) 12126.013 13422.747 14930.6022 13927.5695 14589.1320 60958.791 100 d
apply(MT_mat, 1, anyNA) 11662.390 12546.674 14758.1266 13336.6785 14083.7225 66075.346 100 d
row_sum 1541.594 1581.768 2233.1150 1617.3985 1647.8955 49114.588 100 bc
row_sum_mat 579.161 589.131 707.3710 618.7490 627.5465 3235.089 100 a c
reduce 2028.969 2051.696 2252.8679 2084.8320 2102.8670 4271.127 100 c
complete_case 321.984 330.195 346.8692 342.5115 351.3090 436.057 100 a
complete_case_mat 348.083 358.640 384.1671 379.0205 406.8790 503.503 100 ab
#* Verify that they all return the same result
MT$apply <- apply(MT, 1, anyNA)
MT$apply_mat <- apply(MT_mat, 1, anyNA)
MT$row_sum <- rowSums(is.na(MT)) > 0
MT$row_sum_mat <- rowSums(is.na(MT_mat)) > 0
MT$reduce <- Reduce('|', lapply(MT, is.na))
MT$complete_case <- !complete.cases(MT)
MT$complete_case_mat <- !complete.cases(MT_mat)
all(MT$apply == MT$apply_mat)
all(MT$apply == MT$row_sum)
all(MT$apply == MT$row_sum_mat)
all(MT$apply == MT$reduce)
all(MT$apply == MT$complete_case)
all(MT$apply == MT$complete_case_mat)
complete.cases
似乎是明显的赢家,适用于数据框架和矩阵。事实证明,complete.cases
调用了一个C例程,这可能占其速度的很大一部分。查看rowSums
,apply
和Reduce
会显示R代码。
apply
为rowSums
可能与rowSums
针对特定任务进行优化可能有什么关系。 rowSums
知道它会返回一个数字,apply
没有这样的保证。我怀疑这是否存在所有差异 - 我主要在猜测。
我无法开始告诉你Reduce
是如何运作的。