是否可以在dplyr mutate中使用自定义函数,并选择使用na.rm = TRUE或na.rm = FALSE

时间:2019-08-14 05:17:34

标签: r function dplyr mutate

我有一个使用mutate_at缩放/归一化/ z分数转换多个变量的功能。该函数的源位于链接中: https://dplyr.tidyverse.org/reference/mutate_all.html

scale <- function(x, na.rm = FALSE) (x - mean(x, na.rm = na.rm)) / sd(x, na.rm)

如果初始变量中存在任何NA,则使用该函数会导致所有NA,如以下示例所示:

#make df1
set.seed(123)
df <- data.frame(
  col_A = c(5, NA,2,4, 4,5,8,3,7,9),
  col_B = as.numeric(sample(20:90, size = 10)),
  col_C = as.numeric(sample(1000:2000, size = 10))
)

df

我尝试设置na.rm = TRUE,这似乎实现了我的追求。

scale_narm_true <- function(x, na.rm = TRUE) (x - mean(x, na.rm = na.rm)) / sd(x, na.rm)

vars <- c("col_A", "col_B")
df_z_score <- df %>%
  mutate_at(vars, list(scaled_var = scale)) %>% # introduces NAs in the resulting variables
  mutate_at(vars, list(scaled_narm_true_var = scale_narm_true)) # works as expected and desired

但是,我真正想要的是在实际的mutate_at调用中包括na.rm = TRUE的选项,例如下面的

df_z_score_attempt <- df %>%
  mutate_at(vars, list(scaled_var = scale, na.rm=T)) # this doesn't work!

任何帮助将不胜感激,尤其是因为https://dplyr.tidyverse.org/reference/mutate_all.html认为这是可能的,请指出这是可能的:

starwars %>% mutate_at(c("height", "mass"), scale2, na.rm = TRUE)

1 个答案:

答案 0 :(得分:0)

一种选择是使用~指定匿名函数调用,然后为列获取.

library(dplyr)
df %>%
    mutate_at(vars, list(scaled_var =  ~scale(., na.rm=TRUE)) )
#   col_A col_B col_C col_A_scaled_var col_B_scaled_var
#1      5    50  1373       -0.0952381       -0.8939893
#2     NA    70  1664               NA        0.3306536
#3      2    33  1601       -1.3809524       -1.9349357
#4      4    86  1602       -0.5238095        1.3103678
#5      4    61  1767       -0.5238095       -0.2204357
#6      5    69  1708       -0.0952381        0.2694214
#7      8    62  1090        1.1904762       -0.1592036
#8      3    56  1952       -0.9523810       -0.5265964
#9      7    71  1347        0.7619048        0.3918857
#10     9    88  1648        1.6190476        1.4328321

如果使用默认选项,则该列将为NA

df %>%
    mutate_at(vars, list(scaled_var = scale) )
#   col_A col_B col_C col_A_scaled_var col_B_scaled_var
#1      5    50  1373               NA       -0.8939893
#2     NA    70  1664               NA        0.3306536
#3      2    33  1601               NA       -1.9349357
#4      4    86  1602               NA        1.3103678
#5      4    61  1767               NA       -0.2204357
#6      5    69  1708               NA        0.2694214
#7      8    62  1090               NA       -0.1592036
#8      3    56  1952               NA       -0.5265964
#9      7    71  1347               NA        0.3918857
#10     9    88  1648               NA        1.4328321