фильтровать бесконечные значения и NAS в одном вызове, используя dplyr::c_across и filter_if

#r #dplyr #na

#r #dplyr #na

Вопрос:

Я хочу фильтровать dataframe строки с помощью Inf и NA в одном вызове, используя filter with c_across и устаревшие filter_if :

 library(dplyr)

df <- tibble(a = c(1, 2, 3, NA, 1), b = c(5, Inf, 8, 8, 3), c = c(9, 10, Inf, 11, 12), d = c('a', 'b', 'c', 'd', 'e'), e = c(1, 2, 3, 4, -Inf))
# # A tibble: 5 x 5
#       a     b     c d         e
#   <dbl> <dbl> <dbl> <chr> <dbl>
# 1     1     5     9 a         1
# 2     2   Inf    10 b         2
# 3     3     8   Inf c         3
# 4    NA     8    11 d         4
# 5     1     3    12 e      -Inf
 
  

Я мог бы сделать это в двух вызовах, используя либо c_across , либо filter_if :

 df %>% 
  rowwise %>% 
  filter(!any(is.infinite(c_across(where(is.numeric))))) %>% 
  filter(!any(is.na(c_across(where(is.numeric)))))
# # A tibble: 1 x 5
# # Rowwise: 
#       a     b     c d         e
#   <dbl> <dbl> <dbl> <chr> <dbl>
# 1     1     5     9 a         1

#OR filter_if:
df %>% 
  filter_if(~is.numeric(.), all_vars(!is.infinite(.))) %>% 
  filter_if(~is.numeric(.), all_vars(!is.na(.)))
# # A tibble: 1 x 5
#       a     b     c d         e
#   <dbl> <dbl> <dbl> <chr> <dbl>
# 1     1     5     9 a         1
  

Как бы я выполнил оба подхода за один вызов filter filter_if )? Может быть across подход тоже?

Спасибо

Ответ №1:

Попробуйте это. Используйте where для определения ваших числовых столбцов.

  df %>% 
  filter(across(.cols = where(is.numeric),
                .fns = ~!is.infinite(.x) amp; !is.na(.x)))
  

Ответ №2:

Я бы предложил подход с across() из dplyr :

 library(dplyr)
#Data
df <- tibble(a = c(1, 2, 3, NA, 1),
             b = c(5, Inf, 8, 8, 3),
             c = c(9, 10, Inf, 11, 12),
             d = c('a', 'b', 'c', 'd', 'e'),
             e = c(1, 2, 3, 4, -Inf))
#Mutate
df %>% filter(across(c(a:e), ~ !is.na(.) amp; !is.infinite(.)))
  

Вывод:

 # A tibble: 1 x 5
      a     b     c d         e
  <dbl> <dbl> <dbl> <chr> <dbl>
1     1     5     9 a         1
  

Комментарии:

1. Было бы лучше использовать across(where(is.numeric), ...) для выбора столбцов