mutate_if的正确语法

Kon*_*rad 48 r na dplyr

我想NA通过mutate_ifin 用零替换值dplyr.语法如下:

set.seed(1)
mtcars[sample(1:dim(mtcars)[1], 5),
       sample(1:dim(mtcars)[2], 5)] <-  NA

require(dplyr)

mtcars %>% 
    mutate_if(is.na,0)

mtcars %>% 
    mutate_if(is.na, funs(. = 0))
Run Code Online (Sandbox Code Playgroud)

返回错误:

错误vapply(tbl, p, logical(1), ...):值必须为长度1,但FUN(X[[1]])结果为长度32

这个操作的正确语法是什么?

Hon*_*Ooi 45

"if"in mutate_if表示选择而不是行.例如,mutate_if(data, is.numeric, ...)意味着对数据集中的所有数字列执行转换.

如果要在数字列中用零替换所有NA:

data %>% mutate_if(is.numeric, funs(ifelse(is.na(.), 0, .)))
Run Code Online (Sandbox Code Playgroud)

  • 工作正常,人们可能会使用`if_else`代替留在`tidyverse`并受益于对TRUE,FALSE类型一致性的额外检查 (3认同)

yif*_*yan 36

我从purrr教程中学到了这个技巧,它也适用于dplyr.有两种方法可以解决此问题:
首先,在管道外定义自定义函数,并在mutate_if()以下位置使用它:

any_column_NA <- function(x){
    any(is.na(x))
}
replace_NA_0 <- function(x){
    if_else(is.na(x),0,x)
}
mtcars %>% mutate_if(any_column_NA,replace_NA_0)
Run Code Online (Sandbox Code Playgroud)

其次,使用的组合~,..x(.x可以替换.,但不排除任何其它字符或符号):

mtcars %>% mutate_if(~ any(is.na(.x)),~ if_else(is.na(.x),0,.x))
#This also works
mtcars %>% mutate_if(~ any(is.na(.)),~ if_else(is.na(.),0,.))
Run Code Online (Sandbox Code Playgroud)

在您的情况下,您还可以使用mutate_all():

mtcars %>% mutate_all(~ if_else(is.na(.x),0,.x))
Run Code Online (Sandbox Code Playgroud)

使用~,我们可以定义一个匿名函数,同时.x.代表变量.在mutate_if()的情况下,.或者.x是每一列.


Net*_*tle 11

mtcars %>% mutate_if(is.numeric, replace_na, 0)
Run Code Online (Sandbox Code Playgroud)