代码之家  ›  专栏  ›  技术社区  ›  Rappster

使用谓词函数整齐地替换缺少的值

  •  1
  • Rappster  · 技术社区  · 7 年前

    推荐的整洁的更换方法是什么 NA 与使用 谓词函数?

    我希望利用 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
    

    由Reprex软件包(v0.2.1)于2019-01-21创建

    1 回复  |  直到 7 年前
        1
  •  1
  •   akrun    7 年前

    如果我们正在使用 ~ ,然后指定 . 也即

    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))