我有一个使用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)
答案 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