dplyr编程指南:掌握数据掩码与整洁选择
dplyr 项目地址: https://gitcode.com/gh_mirrors/dpl/dplyr
引言
dplyr作为R语言中最受欢迎的数据处理包之一,其强大之处在于提供了直观且一致的语法。然而,当从交互式使用转向编程时,许多用户会遇到困惑。本文将深入解析dplyr中的两大核心概念——数据掩码(Data Masking)和整洁选择(Tidy Selection),并展示如何在函数和循环中有效运用它们。
数据掩码基础
什么是数据掩码
数据掩码允许我们在dplyr函数中直接使用数据框中的列名,而无需重复引用数据框名称。比较以下两种写法:
传统R写法:
starwars[starwars$homeworld == "Naboo" & starwars$species == "Human", ]
dplyr写法:
starwars %>% filter(homeworld == "Naboo", species == "Human")
数据掩码显著减少了代码冗余,提升了可读性。
环境变量与数据变量
理解数据掩码的关键在于区分两种"变量":
- 环境变量(env-variables):编程中的变量,存在于环境中,通常用
<-
创建 - 数据变量(data-variables):数据集中的列,存在于数据框中
例如:
df <- data.frame(x = runif(3), y = runif(3)) # df是环境变量,x和y是数据变量
df$x # 从环境变量中提取数据变量
数据掩码编程技巧
间接引用问题
在编程时,我们常常需要通过变量间接引用数据列,这时会遇到挑战。
情况1:函数参数传递
当需要通过函数参数传递列名时,使用{{}}
(拥抱操作符):
var_summary <- function(data, var) {
data %>%
summarise(n = n(), min = min({{ var }}), max = max({{ var }}))
}
mtcars %>% var_summary(mpg)
情况2:字符向量引用
当列名存储在字符向量中时,使用.data
代词:
for (var in names(mtcars)) {
mtcars %>% count(.data[[var]]) %>% print()
}
动态列名生成
使用:=
和glue语法可以动态生成列名:
name <- "susan"
tibble("{name}" := 2) # 创建名为"susan"的列
my_df <- function(x) {
tibble("{{x}}_2" := x * 2) # 基于参数名创建列名
}
整洁选择机制
整洁选择DSL
整洁选择提供了一套迷你语言,用于按位置、名称或类型选择列:
select(df, 1)
:选择第一列select(df, starts_with("a"))
:选择所有以"a"开头的列select(df, where(is.numeric))
:选择所有数值列
整洁选择编程
函数参数传递
与数据掩码类似,使用{{}}
:
summarise_mean <- function(data, vars) {
data %>% summarise(n = n(), across({{ vars }}, mean))
}
字符向量引用
使用all_of()
或any_of()
:
vars <- c("mpg", "vs")
mtcars %>% select(all_of(vars)) # 精确选择
mtcars %>% select(!all_of(vars)) # 反向选择
实用编程模式
多表达式处理
接受任意数量表达式时使用...
:
my_summarise <- function(.data, ...) {
.data %>%
group_by(...) %>%
summarise(across(c(mass, height), mean, na.rm = TRUE))
}
创建多列输出
返回无名数据框可在单个表达式中创建多列:
quantile_df <- function(x, probs = c(0.25, 0.5, 0.75)) {
tibble(val = quantile(x, probs), quant = probs)
}
df %>%
group_by(grp) %>%
summarise(quantile_df(x, probs = .5))
变量转换模式
结合across()
和pick()
处理多组变量:
my_summarise <- function(data, group_var, summarise_var) {
data %>%
group_by(pick({{ group_var }})) %>%
summarise(across({{ summarise_var }}, mean, .names = "mean_{.col}"))
}
高级应用场景
Shiny集成
在Shiny应用中,输入控件通常返回字符向量,可使用.data
代词:
server <- function(input, output, session) {
data <- reactive(filter(diamonds, .data[[input$var]] > 0))
output$output <- renderTable(head(data()))
}
多变量循环处理
对字符向量中的多个变量循环处理:
purrr::map(names(mtcars), ~count(mtcars, .data[[.x]]))
总结
掌握dplyr的编程技术需要理解数据掩码和整洁选择的核心概念。关键要点包括:
- 区分环境变量和数据变量
- 函数编程时使用
{{}}
传递参数 - 字符向量引用时使用
.data
或all_of()
- 动态列名生成使用
:=
和glue语法
这些技术将帮助您从dplyr的交互式使用平滑过渡到编程式使用,构建更强大、更灵活的数据处理流程。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考