Чистая замена отсутствующих значений в сочетании с использованием функции предиката - PullRequest
0 голосов
/ 21 января 2019

Каков рекомендуемый аккуратный способ замены NA s в сочетании с использованием предикатная функция?

Я надеялся каким-то образом использовать tidyr::replace_na() (или подобный предопределенный обработчик пропущенных значений), но я не могу заставить его работать с purrr или dplyr способом использования функций предикатов .

library(magrittr)

# Example data:
df <- tibble::tibble(
  id = c(rep("A", 3), rep("B", 3)),
  x = c(1, 2, NA, 10, NA, 30),
  y = c("a", NA, "c", NA, NA, "f")
)

# Works, but needs manual spec of columns that should be handled:
df %>% 
  tidyr::replace_na(list(x = 0))  
#> # A tibble: 6 x 3
#>   id        x y    
#>   <chr> <dbl> <chr>
#> 1 A         1 a    
#> 2 A         2 <NA> 
#> 3 A         0 c    
#> 4 B        10 <NA> 
#> 5 B         0 <NA> 
#> 6 B        30 f

# Doesn't work (at least not in the intended way):
df %>% 
  dplyr::mutate_if(
    function(.x) inherits(.x, c("integer", "numeric")),
    ~tidyr::replace_na(0)  
  )
#> # A tibble: 6 x 3
#>   id        x y    
#>   <chr> <dbl> <chr>
#> 1 A         0 a    
#> 2 A         0 <NA> 
#> 3 A         0 c    
#> 4 B         0 <NA> 
#> 5 B         0 <NA> 
#> 6 B         0 f

# Works, but uses an inline def of the replacement function:
df %>% 
  dplyr::mutate_if(
    function(.x) inherits(.x, c("integer", "numeric")),
    function(.x) dplyr::if_else(is.na(.x), 0, .x)
  )
#> # A tibble: 6 x 3
#>   id        x y    
#>   <chr> <dbl> <chr>
#> 1 A         1 a    
#> 2 A         2 <NA> 
#> 3 A         0 c    
#> 4 B        10 <NA> 
#> 5 B         0 <NA> 
#> 6 B        30 f

# Works, but uses an inline def of the replacement function:
df %>% 
  purrr::modify_if(
    function(.x) inherits(.x, c("integer", "numeric")),
    function(.x) dplyr::if_else(is.na(.x), 0, .x)
  )
#> # A tibble: 6 x 3
#>   id        x y    
#>   <chr> <dbl> <chr>
#> 1 A         1 a    
#> 2 A         2 <NA> 
#> 3 A         0 c    
#> 4 B        10 <NA> 
#> 5 B         0 <NA> 
#> 6 B        30 f

Создано в 2019-01-21 пакетом представлением (v0.2.1)

1 Ответ

0 голосов
/ 21 января 2019

Если мы используем ~, то укажите также ., то есть

df %>%
   mutate_if(function(.x) inherits(.x, c("integer", "numeric")), 
           ~ replace_na(., 0))
# A tibble: 6 x 3
#  id        x y    
#  <chr> <dbl> <chr>
#1 A         1 a    
#2 A         2 <NA> 
#3 A         0 c    
#4 B        10 <NA> 
#5 B         0 <NA> 
#6 B        30 f    

, в противном случае просто сделайте

df %>% 
  mutate_if(function(.x) inherits(.x, c("integer", "numeric")), 
      replace_na, replace = 0)
# A tibble: 6 x 3
#  id        x y    
#  <chr> <dbl> <chr>
#1 A         1 a    
#2 A         2 <NA> 
#3 A         0 c    
#4 B        10 <NA> 
#5 B         0 <NA> 
#6 B        30 f    

Или другой вариант -

df %>% 
   mutate_if(funs(inherits(., c("integer", "numeric"))), 
              ~ replace_na(., 0))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...