深入理解dplyr中的编程技巧:数据掩码与整洁选择

深入理解dplyr中的编程技巧:数据掩码与整洁选择

dplyr dplyr: A grammar of data manipulation dplyr 项目地址: https://gitcode.com/gh_mirrors/dp/dplyr

前言

dplyr作为R语言中最受欢迎的数据处理包之一,其强大的数据操作能力很大程度上依赖于两种关键技术:数据掩码(Data Masking)和整洁选择(Tidy Selection)。本文将深入探讨这两种技术的原理、应用场景以及如何在编程中灵活运用它们。

数据掩码(Data Masking)详解

什么是数据掩码

数据掩码是dplyr中一项革命性的技术,它允许我们直接在函数中引用数据框中的列名,而不需要重复输入数据框名称。这种设计极大地简化了数据操作的语法。

# 传统R语法
starwars[starwars$homeworld == "Naboo" & starwars$species == "Human", ]

# 使用dplyr和数据掩码
starwars %>% filter(homeworld == "Naboo", species == "Human")

环境变量与数据变量

理解数据掩码的关键在于区分两种"变量":

  1. 环境变量(env-variables):编程中的变量,存在于环境中,通常用<-创建
  2. 数据变量(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 }}))
}
  1. 字符向量引用:使用.data代词和[[ ]]操作符
for (var in names(mtcars)) {
  mtcars %>% count(.data[[var]]) %>% print()
}

动态命名技巧

dplyr支持使用:=进行动态列命名:

name <- "susan"
tibble("{name}" := 2)  # 使用glue语法插入变量名

my_df <- function(x) {
  tibble("{{x}}_2" := x * 2)  # 使用拥抱语法基于参数命名
}

整洁选择(Tidy Selection)技术

整洁选择DSL

整洁选择提供了一套迷你领域特定语言,用于按名称、位置或类型选择列:

  • select(df, 1) 选择第一列
  • select(df, starts_with("a")) 选择所有以"a"开头的列
  • select(df, where(is.numeric)) 选择所有数值列

间接选择方法

  1. 参数传递时的选择:使用双大括号{{ }}
summarise_mean <- function(data, vars) {
  data %>% summarise(n = n(), across({{ vars }}, mean))
}
  1. 字符向量选择:使用all_of()any_of()
vars <- c("mpg", "vs")
mtcars %>% select(all_of(vars))
mtcars %>% select(!all_of(vars))

实用编程模式

用户提供数据

当函数接受用户提供的数据框时,通常不需要特殊处理:

mutate_y <- function(data) {
  mutate(data, y = a + x)
}

处理多个表达式

  1. 单个用户表达式
my_summarise <- function(data, expr) {
  data %>% summarise(
    mean = mean({{ expr }}),
    sum = sum({{ expr }}),
    n = n()
  )
}
  1. 多个用户表达式
my_summarise3 <- function(data, mean_var, sd_var) {
  data %>% 
    summarise(mean = mean({{ mean_var }}), sd = sd({{ sd_var }}))
}
  1. 动态列命名
my_summarise4 <- function(data, expr) {
  data %>% summarise(
    "mean_{{expr}}" := mean({{ expr }}),
    "sum_{{expr}}" := sum({{ expr }}),
    "n_{{expr}}" := n()
  )
}

任意数量表达式

使用...接受任意数量的表达式:

my_summarise <- function(.data, ...) {
  .data %>%
    group_by(...) %>%
    summarise(mass = mean(mass, na.rm = TRUE), height = mean(height, na.rm = TRUE))
}

创建多列输出

返回未命名的数据框可以创建多列:

quantile_df <- function(x, probs = c(0.25, 0.5, 0.75)) {
  tibble(val = quantile(x, probs), quant = probs)
}

summarise中使用时设置.unpack = TRUE

df %>%
  group_by(grp) %>%
  summarise(across(x:y, ~ quantile_df(.x, probs = .5), .unpack = TRUE))

变量转换模式

使用across()pick()转换用户提供的变量:

my_summarise <- function(data, summary_vars) {
  data %>% summarise(across({{ summary_vars }}, ~ mean(., na.rm = TRUE)))
}

控制输出列名:

my_summarise <- function(data, group_var, summarise_var) {
  data %>%
    group_by(pick({{ group_var }})) %>% 
    summarise(across({{ summarise_var }}, mean, .names = "mean_{.col}"))
}

循环处理技术

  1. 基本循环
for (var in names(mtcars)) {
  mtcars %>% count(.data[[var]]) %>% print()
}
  1. 函数式编程
mtcars %>% 
  names() %>% 
  purrr::map(~ count(mtcars, .data[[.x]]))

总结

掌握dplyr中的数据掩码和整洁选择技术可以显著提高数据操作代码的效率和可读性。关键要点包括:

  1. 理解环境变量和数据变量的区别
  2. 掌握{{ }}拥抱操作和.data代词的使用场景
  3. 熟练运用across()pick()进行多变量操作
  4. 了解动态列命名和循环处理的技术

这些技术组合使用可以解决绝大多数数据操作编程中的挑战,使你的dplyr代码更加灵活和强大。

dplyr dplyr: A grammar of data manipulation dplyr 项目地址: https://gitcode.com/gh_mirrors/dp/dplyr

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鲍爽沛David

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值