SuperAPI AI 工具集

designing-tidy-r-functions

编程与开发

查看项目

更新于 10-16 09:12

技能介绍

用途

本文档用于指导 R 函数 API 的设计、R 代码设计问题的评审、R 包函数的编写,以及参数顺序与命名决策的评估。其核心理念是:为人类而非计算机设计 R 函数,以降低认知负担、提升可预测性与可组合性。文中强调这些原则适用于任何 R 代码,而不限于 tidyverse 包。

主要能力

文档以「快速参考」表与大量正反例代码的形式,给出一系列可操作的设计模式:可预测的命名、清晰的参数、管道友好、类型稳定、枚举选项、副作用处理、复杂策略抽取等。

函数命名

  • 使用祈使语气的动词,例如 mutate()、filter()、summarize();名词式构建器(如 geom_point()、recipe())属于例外。
  • 优先使用前缀而非后缀,因为前缀便于自动补全发现,例如 str_detect()、str_replace()、str_extract()、read_csv()、read_tsv()、read_delim();后缀用于同一主题的变体,例如 map_int()、map_chr()、map_dbl()。
  • 命名长度与使用频率成反比:高频用短名(c()、n()、df),低频用描述性名称(create_bootstrap_samples()、validate_model_specification())。

参数设计

  • 最重要的参数放在最前,例如 str_replace(string, pattern, replacement)、left_join(x, y, by);决定输出的参数靠前,例如 read_csv(file, col_types, col_names)。
  • 必填参数不设默认值;反例是让所有参数都有默认值。
  • ... 的位置很重要,应放在必填参数与可选参数之间,从而强制后续可选参数显式命名,例如 my_function <- function(x, y, ..., verbose = FALSE, na.rm = TRUE)。
  • 默认值保持简短,复杂默认值用 NULL 表示并在函数体内计算(如 weights <- weights %||% rep(1, length(x))),而不是把复杂表达式直接写在签名里。
  • 枚举字符串选项时使用 arg_match() 配合字符向量默认值,例如 method = c("fast", "accurate", "balanced"),首个值为默认值并完成校验。
  • 标准化常用参数名:预测新数据用 new_data(而非 newdata、newData),缺失值处理用 na_rm(而非 na.rm、rm.na),案例权重用 weights(而非 wts、w),预测变量数据框用 x(而非 predictors、features),结果变量用 y(而非 response、target),公式接口数据用 data(而非 df、dataset)。

输出模式

  • 类型稳定性:输出类型应由输入类型而非输入值决定,例如 ifelse() 会因条件值改变返回类型,而 dplyr::if_else() 保持一致。
  • 模型函数的预测输出应为 tibble:与输入行数相同、行顺序相同、列名标准化为 .pred、.pred_class、.pred_lower。
  • 用于副作用的函数应不可见地返回第一个参数(如写入文件的函数返回 invisible(x)),以便链式管道继续使用。

副作用

  • 将副作用与计算分离:不要在计算函数里埋入打印或修改全局状态的代码;可用 verbose 参数控制信息输出。
  • 让副作用易于撤销:修改全局状态的函数应返回原值以便恢复(如 options() 的用法示例)。

策略模式

  • 避免用布尔标志表示策略,因为组合语义不清,例如 grepl() 的 perl、fixed、ignore.case 组合。
  • 对复杂选项使用策略对象与辅助函数,如 regex()、fixed(),主函数按对象类型分派处理。

显式优于隐式

  • 避免依赖全局选项,例如不要从 getOption("na.action") 隐式取值,而应提供带说明性默认值的显式参数。
  • 当默认值重要时应告知用户,例如在时区默认取值时通过 cli::cli_inform() 提示。

模型对象设计

  • 最小化存储数据:只保存预测所需内容(如系数、因子水平),不要把整个训练集存入模型造成内存膨胀。
  • 永不保存 call 对象,因为 call 可能内嵌整个数据集与环境。
  • 使用规范的 S3 构造器:内部 new_my_model()、内部校验器 validate_my_model()、面向用户的辅助函数 my_model()。

矩阵子集

  • 始终保留矩阵结构,使用 X[, 1, drop = FALSE] 而非可能退化为向量的 X[, 1]。

使用方式

文档提供「设计评审检查清单」,在评审 R 函数设计时逐项核对:函数名是否为祈使动词(构建器可为名词)、相关函数是否共享前缀、最重要参数是否靠前、主数据是否为第一个参数(管道友好)、必填参数是否无默认值、... 是否位于必填与可选参数之间、字符串选项是否用 arg_match() 配合枚举默认值、输出类型是否可由输入类型预测、副作用函数是否不可见返回输入、是否存在对全局选项或区域设置的隐藏依赖、策略变化是否用对象而非布尔标志、模型对象是否不存储训练数据与 call、矩阵子集是否使用 drop = FALSE。

适用场景

适合需要设计或评审 R 函数 API、编写 R 包函数、评估参数顺序与命名决策的开发者。文中示例以 tidyverse 与 tidymodels 生态为主,但原则声明适用于任意 R 代码。

限制

资料未提供具体的收费、价格、平台或效果信息,暂未提供。