SuperAPI AI 工具集

rlang-patterns

编程与开发

查看项目

更新于 10-15 08:14

技能介绍

用途

rlang 是支撑 tidyverse 数据掩码(data-masking)的元编程框架。数据掩码允许 R 表达式像引用环境中的变量一样引用数据框的列。本技能面向需要编写使用 tidy evaluation 的 R 函数的开发者,提供现代 rlang 模式,帮助在保持 tidyverse 直观数据掩码体验的同时,实现干净、安全的元编程。

主要能力

核心概念

数据掩码让 R 表达式可以像引用环境变量一样引用数据框列。rlang 提供了驱动 tidyverse 数据掩码的元编程框架。

关键 rlang 工具

  • 拥抱 {{ }}:将函数参数转发到数据掩码函数
  • 注入 !!:注入单个表达式或值
  • 拼接 !!!:从列表注入多个参数
  • 动态点(Dynamic dots):支持注入的可编程 ...
  • 代词 .data/.env:显式区分数据变量与环境变量

函数参数模式

用 {{ }} 转发:使用 {{ }} 将函数参数转发到数据掩码函数。例如:

my_summarise <- function(data, var) {
  data |> dplyr::summarise(mean = mean({{ var }}))
}

可配合任意数据掩码表达式使用,也支持代词语法。

转发 ...(无需特殊语法):简单的点转发可直接将 ... 传给数据掩码函数,也适用于 tidy 选择。对于单参数 tidy 选择,需用 c() 包裹。

使用 .data 的名称模式:用 .data 代词进行程序化列访问,例如通过名称访问单列,或用 all_of() 处理多列。这种方式完全不受数据掩码影响,无歧义。

注入运算符

各运算符的适用场景:

  • {{ }}:转发函数参数,如 summarise(mean = mean({{ var }}))
  • !!:注入单个表达式/值,如 summarise(mean = mean(!!sym(var)))
  • !!!:注入多个参数,如 group_by(!!!syms(vars))
  • .data[[]]:按名称访问列,如 mean(.data[[var]])

使用 !! 的高级注入:可从字符串创建符号;注入值以避免名称冲突;在 tidyeval 上下文中使用 data_sym() 更稳健。

使用 !!! 拼接:可从字符向量创建多个符号,或使用 data_syms() 用于 tidy 上下文;也可拼接参数列表。

动态点模式

使用 list2() 支持动态点:在函数中用 list2() 而非 list() 收集 ...,从而支持正常用法、拼接列表、名称注入、尾随逗号等特性。

使用 glue 语法进行名称注入:可用 "{name}" := 1 创建命名列表;在函数参数中结合 {{ }} 生成列名;也可用 englue() 允许用户自定义名称。

代词消歧

.data 和 .env 最佳实践:显式消歧可防止掩码问题。在循环和程序化上下文中使用 .data[[var]] 等方式访问列。

编程模式

桥接模式:在数据掩码与 tidy 选择行为之间转换。across() 可作为选择到数据掩码的桥接;across(all_of()) 可作为名称到数据掩码的桥接。

转换模式:通过包裹转换单个参数;用 across() 转换点;也可手动转换(高级)。

应避免的易错模式

  • 避免字符串解析与 eval(安全风险),应使用符号创建与注入
  • 避免在数据掩码中使用 get()(名称冲突),应使用显式注入或 .data
  • 不要对非参数使用 {{ }}
  • 不要不必要地混用注入风格,选定一种并坚持

包开发

导入策略:在 DESCRIPTION 中 Imports: rlang;在 NAMESPACE 中导入特定函数,或使用 @importFrom 标签。

文档标签:使用 data-masked、dynamic-dots、tidy-select 等标签标注参数。

测试 rlang 函数:测试数据掩码行为与注入行为。

使用方式

本技能以模式与代码示例形式提供,涵盖从基础转发到高级注入、名称注入、桥接与转换、包开发与测试的完整流程。开发者可参照示例编写使用 tidy evaluation 的 R 函数。

适用场景

适用于编写使用 tidy evaluation 的 R 函数,尤其是需要将参数转发到 dplyr、tidyr 等数据掩码函数的场景,以及需要程序化访问列名、动态构建参数、在包中集成 rlang 的场景。

限制

资料未提供该技能的安装方式、运行环境要求、版本兼容性、收费或价格信息,暂未提供。