仅将“ mutate_at”和“ na_if”一起用NA替换零

Jer*_* K. 4 r dplyr tidyverse mutate

我的数据采用以下格式:

library(tidyverse)
df <- mtcars
df <- df %>% mutate(vs_doubled = vs * 2) %>% select(mpg, cyl, vs, am, vs_doubled)

head(df)


#>    mpg cyl vs am vs_doubled
#> 1 21.0   6  0  1          0
#> 2 21.0   6  0  1          0
#> 3 22.8   4  1  1          2
#> 4 21.4   6  1  0          2
#> 5 18.7   8  0  0          0
#> 6 18.1   6  1  0          2
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用0 mutate_at并将na_if其设置为NA,但仅用于特定列(“ vs”和“ am”)。我想在列“ vs_doubled”中保留零。

我不太正确,因为以下行不起作用:

df <- df %>% mutate_at(.vars = c("vs", "am"), .funs = na_if(y = 0))
Run Code Online (Sandbox Code Playgroud)

Ron*_*hah 5

我们能做的

library(dplyr)
df %>%  mutate_at(vars(vs,am), ~na_if(.,0)) %>% head

#   mpg cyl vs am vs_doubled
#1 21.0   6 NA  1          0
#2 21.0   6 NA  1          0
#3 22.8   4  1  1          2
#4 21.4   6  1 NA          2
#5 18.7   8 NA NA          0
#6 18.1   6  1 NA          2
Run Code Online (Sandbox Code Playgroud)

或者另一种方式是

df %>% mutate_at(vars(vs,am), na_if, 0)
Run Code Online (Sandbox Code Playgroud)

~是purrr样式的公式语法,而.代表列的值。这是匿名函数调用的替代方法,使用该函数您可以将上面的函数编写为

df %>%  mutate_at(vars(vs,am), function(x) na_if(x, 0)) 
Run Code Online (Sandbox Code Playgroud)

同样,所示的替代方法也不是必需的~,我们可以直接使用附加参数传递函数(此处为0 y)。


当然,还有其他方法可以不使用 na_if

df %>% mutate_at(vars(vs, am), ~replace(., . == 0, NA)) 
Run Code Online (Sandbox Code Playgroud)

或与基数R相同

cols <- c("vs", "am")
df[cols] <- lapply(df[cols], function(x) replace(x, x == 0, NA))
Run Code Online (Sandbox Code Playgroud)

  • 最好能在这里提供 '~' 和 '.' 的作用的基本解释。我喜欢“tidyverse”,但当“tidyverse”问题的答案往往最终是“添加这些任意符号”时,我感到很沮丧。 (2认同)
  • 对于正在寻找〜和。解释的任何人,我发现此链接非常有用https://suzan.rbind.io/2018/02/dplyr-tutorial-2/#mutate-at-to变更专用列 (2认同)