Я хочу идентифицировать имена столбцов, которые заполнены нулями и NA в R - PullRequest
0 голосов
/ 28 июня 2018

У меня есть фрейм данных с примерно 111 столбцами, немногие из столбцов полностью заполнены нулями и NA. Я хочу программно идентифицировать имена столбцов, которые имеют только нули и NA,

Я использовал ниже, чтобы найти столбцы, которые полностью имеют NA

a<-data[,((colSums(is.na(data)) == nrow(data))==T)]
names(a)

Теперь я хочу найти имена столбцов, которые заполнены смесью нулей и NA, как я могу это сделать?

Ответы [ 4 ]

0 голосов
/ 28 июня 2018

Можно попытаться использовать dplyr::select_if, чтобы получить имена столбцов, имеющих только 0 или NA.

library(dplyr)
df %>% select_if(funs(all(is.na(na_if(.,0))))) %>% names()
#[1] "a" "d" "f"

Данные: Данные выборки взяты из @MauritsEvers

0 голосов
/ 28 июня 2018

Это работа для setequal:

dat <- data.frame(a=1:4, b=c(0,NA,1,NA), c=c(0,NA,0,NA), d=c(0,NaN,0,NaN), e=NA, f=0)
names(dat)[sapply(dat, setequal, c(0,NA))]
#[1] "c"

setequal по существу сравнивает уникальные значения двух векторов, чтобы убедиться, что они полностью перекрываются. Смотрите здесь: В чем разница между setequal (a, b) и идентичным (a, b) в R? для получения дополнительной информации.

0 голосов
/ 28 июня 2018

Использование 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).

0 голосов
/ 28 июня 2018

Поскольку вы не предоставляете минимальный репрезентативный набор данных, мы сначала сгенерируем некоторые образцы данных

set.seed(2017);
df <- setNames(data.frame(
    rep(0, 10),
    runif(10),
    runif(10),
    rep(NA, 10),
    runif(10),
    sample(c(NA, 0), 10, replace = T)), letters[1:6])
df;
#   a          b           c  d          e  f
#1  0 0.92424261 0.674331481 NA 0.63411352  0
#2  0 0.53717641 0.002020766 NA 0.37986744 NA
#3  0 0.46919565 0.025093514 NA 0.94207403 NA
#4  0 0.28862618 0.432077786 NA 0.75499369 NA
#5  0 0.77008816 0.499391912 NA 0.22761184  0
#6  0 0.77276871 0.388681932 NA 0.91466603  0
#7  0 0.03932234 0.395375316 NA 0.62044504 NA
#8  0 0.43490560 0.715707325 NA 0.31910458 NA
#9  0 0.47216639 0.940999879 NA 0.07628881 NA
#10 0 0.27383312 0.827229161 NA 0.26083932  0

Тогда мы можем использовать all с is.na и x == 0, чтобы идентифицировать ноль / NA столбцы

names(df)[sapply(df, function(x) all(is.na(x) | x == 0))]
#[1] "a" "d" "f"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...