R data-masking

观察下面代码,不使用 subset 时 R 不知道 "mpg" 是 mtcars 的一列,需要用 mtcars$mpg 指定,但是 subset 函数不需要,因为他有 data-masking.

> mtcars[mpg == 21,]
Error in `[.data.frame`(mtcars, mpg == 21, ) : object 'mpg' not found
> mtcars[mtcars$mpg == 21,]
              mpg cyl disp  hp drat    wt  qsec vs am gear carb
Mazda RX4      21   6  160 110  3.9 2.620 16.46  0  1    4    4
Mazda RX4 Wag  21   6  160 110  3.9 2.875 17.02  0  1    4    4
> subset(mtcars, mpg == 21)
              mpg cyl disp  hp drat    wt  qsec vs am gear carb
Mazda RX4      21   6  160 110  3.9 2.620 16.46  0  1    4    4
Mazda RX4 Wag  21   6  160 110  3.9 2.875 17.02  0  1    4    4

tidyverse 提供了多种 data-masking 方法。

用双花括号 "{{ }}" 解析函数参数值,注意有空格。

library(tidyverse)

dist_summary <- function(df, var) {
  df %>%
    summarise(n = n(), min = min({{ var }}), max = max({{ var }}))
}
mtcars %>% dist_summary(mpg)
mtcars %>% group_by(cyl) %>% dist_summary(mpg)

.data[[var]] 格式解析变量值为数据框的变量(列),而不是环境变量(ls())。比如 count 函数需要输入列名针对该列进行统计,如果是 count(var) 那么会寻找列名为 "var" 的列。

for (var in names(mtcars)) {
  mtcars %>% count(.data[[var]]) %>% print()
}

lapply(names(mtcars), function(var) mtcars %>% count(.data[[var]]))

从变量值创建数据框新列用 := 符号,注意有空格。

var_name <- "l100km"
mtcars %>% mutate("{var_name}" := 235 / mpg)

参考资料
What is data-masking and why do I need
Argument type: data-masking — dplyr_data_masking • dplyr

你可能感兴趣的:(R data-masking)