Использование setequal
в качестве письма было самым ясным, а также различение между NaN
и NA
с. Если вам действительно нужно, чтобы это было быстро, вы можете подумать:
only_zeroes_and_NAs <- function(v) {
is.numeric(v) &&
anyNA(v) &&
suppressWarnings({
# min(v, na.rm = TRUE) will emit a
# warning if all are NA, which we can ignore
min(v, na.rm = TRUE) == 0 &&
max(v, na.rm = TRUE) == 0
})
}
only_zeroes_and_NAs_or_NaN <- function(v) {
is.numeric(v) &&
anyNA(v) &&
suppressWarnings({
# min(v, na.rm = TRUE) will emit a
# warning if all are NA, which we can ignore
min(v, na.rm = TRUE) == 0 &&
max(v, na.rm = TRUE) == 0
}) &&
!any(is.nan(v))
}
set.seed(6)
N = 10e6
dat <- data.frame(a=sample(1:4, size = N, replace = TRUE),
b=sample(c(0,NA,1,NA), size = N, replace = TRUE),
c=sample(c(0,NA,0,NA), size = N, replace = TRUE),
d=sample(c(0,NaN,0,NaN), size = N, replace = TRUE),
e=NA, f=0, g = NA_real_)
bench::mark(me = names(dat)[sapply(dat, only_zeroes_and_NAs)],
me_nan = names(dat)[sapply(dat, only_zeroes_and_NAs_or_NaN)],
setequal = names(dat)[sapply(dat, setequal, c(0, NA))],
check = FALSE,
filter_gc = FALSE)
#> # A tibble: 3 x 10
#> expression min mean median max `itr/sec` mem_alloc n_gc
#> <chr> <bch:tm> <bch:tm> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl>
#> 1 me 331.3ms 331.5ms 331.5ms 331.7ms 3.02 140.16KB 0
#> 2 me_nan 453.2ms 467.5ms 467.5ms 481.8ms 2.14 76.34MB 1
#> 3 setequal 2.1s 2.1s 2.1s 2.1s 0.477 1.69GB 6
#> # ... with 2 more variables: n_itr <int>, total_time <bch:tm>
Создано в 2018-06-28 пакетом Представления (v0.2.0).