☰
ggplot2 反向依赖检查(revdepcheck)结果深度解读:从 6300 个依赖包看 API 变更影响面
2026/10/5 6:43:12 网站建设 项目流程
  • 数据可视化

【免费下载链接】ggplot2

An implementation of the Grammar of Graphics in R

项目地址:https://gitcode.com/gh_mirrors/gg/ggplot2
点击查看免费下载

本文以 ggplot2 仓库 revdep/cran.md 这份官方反向依赖(reverse dependency)检查报告为核心,完整解读本轮 revdepcheck 的规模、方法、2 个新增问题与 160 个未能完成检查的包,并结合 R/stat-boxplot.R、NEWS.md 等源码佐证问题背后的 API 变更。读者阅读后将掌握反向依赖检查的运作机制、如何阅读与复现这类报告,以及如何基于检查结果定位依赖生态中的兼容性问题。

一、反向依赖检查是什么:revdepcheck 的双版本对照方法

revdep/cran.md是 ggplot2 在发布 dev 版本前例行执行的一轮"生态体检"结果。其核心方法是:对每个反向依赖包,分别在两个环境下运行R CMD check——一次使用当前 CRAN 上已发布的 ggplot2 版本,一次使用本仓库的 dev 版本,然后逐包比较两次检查结果。原文对这一方法的描述非常明确:

We checked 6300 reverse dependencies (6276 from CRAN + 24 from Bioconductor), comparing R CMD check results across CRAN and dev versions of this package.

这一对照设计的价值在于:

  • CRAN 版本结果代表"现状基线",即这些包在当前稳定版 ggplot2 上本来的检查状态;
  • dev 版本结果代表"变更后状态",即如果用户升级到新版本 ggplot2,这些包会发生什么;
  • 只有在 dev 下新出现(Newly broken)、而 CRAN 下正常的问题,才可能与本仓库的改动有关,值得维护者逐个排查。

配套的 revdep/problems.md 按包记录"Newly broken"与"In both"两类明细,revdep/failures.md 则存放所有未能完成检查的包的完整日志,revdep/README.md 以表格形式汇总了失败包的版本号与错误/警告/提示计数(注意:README 表格快照记录的是 184 个失败包,与 cran.md 本轮记录的 160 个数值不同,可以推断两份文件对应不同轮次的检查运行)。

二、本轮检查总览:规模与关键数字

报告开头给出了三个核心统计,是判断一次发布"风险面"的首要指标:

指标数值含义
反向依赖总数6300(6276 CRAN + 24 Bioconductor)依赖 ggplot2 的全部包数量
新增问题(New problems)2在 dev 版 ggplot2 下新出现的失败/警告
未能完成检查(Failed to check)160因依赖缺失、环境等原因无法给出结论的包

值得强调的是,"新增问题"只有 2 个,而受检包多达 6300 个,说明本轮 dev 改动对下游生态的破坏面非常小;"未能完成检查"的 160 个包则大多数与 ggplot2 本身无关(详见第五节),这恰恰是反向依赖检查要帮维护者区分开的两种情况。

三、新增问题一:ggdibbler 的代码/文档不一致(WARNING)

3.1 检查输出原文

* ggdibbler checking for code/documentation mismatches ... WARNING

revdep/problems.md 给出了完整细节:ggdibbler(版本 0.6.1)在R CMD check的 "code/documentation mismatches"(codoc)检查中报警。该检查会比对函数签名与 Rd 文档中\usage的一致性,完整输出如下:

Codoc mismatches from Rd file 'geom_boxplot_sample.Rd': stat_boxplot_sample Code: function(mapping = NULL, data = NULL, geom = "boxplot", position = "identity", ..., times = 10, orientation = NA, seed = NULL, coef = 1.5, quantile.type = 7, na.rm = FALSE, show.legend = NA, inherit.aes = TRUE) Docs: function(mapping = NULL, data = NULL, geom = "boxplot", position = "identity", ..., times = 10, orientation = NA, seed = NULL, coef = 1.5, na.rm = FALSE, show.legend = NA, inherit.aes = TRUE) Argument names in code not in docs: quantile.type Mismatches in argument names: Position: 10 Code: quantile.type Docs: na.rm Position: 11 Code: na.rm Docs: show.legend Position: 12 Code: show.legend Docs: inherit.aes

3.2 与 ggplot2 源码的关联

这个 WARNING 出现在 ggdibbler 自己实现的stat_boxplot_sample上:它的函数代码里新增了quantile.type = 7参数,但 Rd 文档没有同步更新。从签名看,该参数几乎是对 ggplot2 新 API 的镜像——ggplot2 恰恰在本轮 dev 版本中为箱线图统计变换新增了同名参数:

  • NEWS.md 第 52 行记录:"geom_boxplot()/stat_boxplot()gain aquantile.typeparameter (default7) to control the percentile definition used for hinges and median; setquantile.type = 2...";
  • 在 R/stat-boxplot.R 中,StatBoxplot$compute_group的函数签名包含quantile.type = 7(第 56 行),实际计算时通过stats::quantile(data$y, qs, type = quantile.type)(第 65 行)将参数透传给 R 底层的分位数算法;
  • 文档注解(第 103-104 行)说明:quantile.type是 1 到 9 之间的整数,用于选择分位数算法,默认7(与stats::quantile的默认类型一致)。

参数默认值同为7、位置同为第 10 位,这从侧面印证 ggdibbler 的stat_boxplot_sample在跟随 ggplot2 的 API 演进,只是漏更新了自己的 Rd 文档。对 ggdibbler 维护者而言,修复方式很简单:在geom_boxplot_sample.Rd的\usage与参数说明中补上quantile.type,或在函数中显式声明该参数已弃用。

3.3 该参数在 ggplot2 内部的语义

为什么quantile.type值得关注?箱线图的 hinges(四分位点)和 median 对分位数算法的选择敏感,尤其在小样本下不同type会给出不同结果。ggplot2 提供了针对性测试来锁定这一行为:

  • tests/testthat/test-geom-boxplot.R 验证:对y = c(1, 2, 3, 4)这样的小样本,quantile.type = 2与默认值(type = 7)会得到不同的 lower/upper hinges;
  • 同文件第 127-140 行验证向后兼容性:quantile.type = 7的结果与旧默认行为完全一致。

也就是说,新参数默认值刻意保持与旧行为一致(type 7),只有用户显式设置其他值时结果才变化——这是 ggplot2 在引入新能力时"默认不破坏下游"的典型策略,也是本轮 6300 个包中仅出现 2 个新问题的原因之一。

四、新增问题二:simRestore 的测试失败(ERROR)

4.1 检查输出原文

* simRestore checking tests ... ERROR

revdep/problems.md 给出了 simRestore(版本 1.1.5)的 testthat 失败细节:

Running 'testthat.R' Running the tests in 'tests/testthat.R' failed. Complete output: > library(testthat) > library(simRestore) > > test_check("simRestore") Saving _problems/test-optimize_static-21.R Saving _problems/test-optimize_static-22.R [ FAIL 2 | WARN 0 | SKIP 0 | PASS 79 ] ... ── Failure ('test-optimize_static.R:22:3'): simple optimization ──────────────── Expected `length(vx$results$t)` to equal 5. Differences: 1/1 mismatches [1] 4 - 5 == -1 [ FAIL 2 | WARN 0 | SKIP 0 | PASS 79 ] Error: ! Test failures. Execution halted

4.2 输出解读

逐行拆解这段日志:

  • [ FAIL 2 | WARN 0 | SKIP 0 | PASS 79 ]:testthat 汇总,79 个测试通过、2 个失败;
  • 失败发生在test-optimize_static.R:22的 "simple optimization" 用例:断言length(vx$results$t)应为 5,实际为 4;
  • 差异行[1] 4 - 5 == -1是 testthat 的expect_equal输出格式,即actual - expected = -1;
  • Saving _problems/test-optimize_static-21.R等两行表明 simRestore 在失败时保存了复现用的中间文件。

从仓库现有材料看,该失败是"优化结果的迭代步数由 5 变为 4"这类数值型回归,被归入 "Newly broken"(dev 下新出现)。但由于本仓库只包含 ggplot2 自身源码,无法进一步确认 simRestore 内部vx$results$t与 ggplot2 哪一具体改动相关,报告方给出的排查入口是revdepcheck::cloud_details(, "simRestore")获取云端检查的完整上下文。

五、未能完成检查的 160 个包:名单与原因分类

5.1 完整名单

cran.md 以(NA)标记列出全部 160 个未能完成检查的包,完整名单如下(顺序与原文一致):

apsimx aridagri autovi AVGAS bayesdfa BGGM BGmisc bmm boinet brms BSL bullseye cases cassowaryr cdcatR cheem ChillModels chouca cinaR ClustAssess ClusterGVis clusterMI ClustImpute CompAREdesign copulaSim correlation ctsem cylcop daltoolbox decisionSupport deepSTRAPP DFD dimRed dMrs DstarM easybgm eda4treeR EFDR EGAnet ER FAfA fastei fastqrs FCPS fddm FeatureImpCluster ferrn ffp fio gasmodel GDINA gemR genekitr GeneralizedUmatrixGPU ggpicrust2 ggsem GJRM grandR gratia GRIDCOPULA harbinger hbsaems heimdall IndGenErrors ivolcano jmv latentFactoR lcsm linkspotter lionfish LMMstar LongDecompHE manymome MD2sample MDgof measureR metrica mgc micemd MiscMetabar MixedIndTests MixMashNet modelbased ModStatR morepls mulgar multinma MVN negligible numbat OlinkAnalyze OpenMx outstandR pandemonium parameters pctax pcutils phylosem polarisR predictionInterval prefviz projectLSA psychonetrics pvars qad qmd QuadratiK quollr rattle RCTrep ReporterScore Revticulate RGENERATEPREC ridgetorus rmedsem RMOPI rmsb rSDR rshift RSP rstanarm RulesTools SCpubr semtree Signac simcausal SimDesign spareg spinebil spinifex Spower sprtt SRscore STCCGEV STCYP streamDAG SurprisalAnalysis Surrogate svars TCIU TDAkit TELP tepr TestAnaAPP tidybins tidycomm tidylearn tidySEM tinyarray tourr TransProR TriDimRegression ufs VecDep WINS wmwAUC woylier WQM XYomics zenplots

5.2 失败原因分类

cran.md 本身只给出(NA),但 revdep/failures.md 保留了每包在 devel 与 CRAN 两个环境的完整R CMD check日志,据此可以将失败原因归纳为几类:

第一类:依赖包在当前环境中不可用(最常见)。典型日志形如Package required but not available: 'xxx',例如:

  • BGGM 缺少BFpack、bmm 缺少rtdists、BSL/boinet/cases 缺少copula、bayesdfa 缺少rstantools(安装阶段loadNamespace(x)报 "there is no package called 'rstantools'")。这类失败纯粹是检查环境的依赖解析问题,与 ggplot2 的改动无关。

第二类:在 devel 与 CRAN 两个版本下表现一致的问题(即 "In both")。例如 apsimx 在两种环境下均为 "Status: 2 NOTEs",autovi 两版均为 "Status: OK",说明这些包的问题(或正常状态)是预先存在的,不受 ggplot2 dev 版影响,不应归咎于本次变更。

第三类:安装前即失败(Error before installation)。如 AVGAS 在两版环境中都出现checking whether package 'AVGAS' can be installed ... ERROR,属于包自身安装问题。

理解"未能完成检查 ≠ ggplot2 破坏"这一点很重要:160 个(NA)包中绝大多数是环境性失败,真正的风险信号只来自第三节、第四节的 2 个 "Newly broken"。

六、如何复现与深入排查

报告本身是静态快照,若要跟进某个包,官方给出了两条线索:

  1. 云端详情:对任一受检包执行revdepcheck::cloud_details(, "ggdibbler")(包名替换为"simRestore"、"apsimx"等)可获取该包在云端的完整检查元数据,包括版本、发布时间、递归依赖数量(如 ggdibbler 160 个、simRestore 78 个)以及日志位置。

  2. 本地复现:针对 "Newly broken" 的问题,可以在本仓库 dev 版本基础上对该包单独运行R CMD check,复现步骤为——先devtools::load_all()加载仓库当前代码,再从 CRAN 安装对应版本的依赖包,最后对目标包运行R CMD check /path/to/package,重点核对 problems.md 中给出的检查项(codoc、tests)与日志行号。

对于想在自己的包中规避同类问题的开发者,本仓库的实践可作参考:当 ggplot2 新增或调整参数时,先核对自身函数签名与 Rd 文档是否同步(避免 ggdibbler 式的 codoc 警告),再用 testthat 锁定与旧行为的兼容性(参考 tests/testthat/test-geom-boxplot.R 中quantile.type = 7与默认行为一致的断言模式)。

七、从检查结果看 ggplot2 的 API 演进策略

把三份报告(revdep/cran.md、revdep/problems.md、revdep/failures.md)放在一起,可以归纳出 ggplot2 维护者在做 API 变更时的几条可验证策略:

  • 默认向后兼容:新增quantile.type时默认值取7,与stats::quantile的 R 默认算法一致(R/stat-boxplot.R),并配套"默认行为不变"的回归测试,最大限度降低下游包的行为漂移;
  • 生态体检前置:发布前对全部反向依赖做 CRAN vs dev 双版本对照检查,用数字(2/6300)而非感觉判断变更风险;
  • 问题分级处置:将 "Newly broken"(可能与本次变更相关)与 "In both"/"无法检查"(大概率与本次变更无关)严格区分,避免把环境问题误判为回归。

对任何维护大型 R 生态包(或自建依赖树)的开发者而言,这份报告就是一份可直接借鉴的"发布前兼容性检查模板":明确受检范围、双版本对照、按新/旧问题分级、并为每个问题保留可复现日志。

  • 数据可视化

【免费下载链接】ggplot2

An implementation of the Grammar of Graphics in R

项目地址:https://gitcode.com/gh_mirrors/gg/ggplot2
点击查看免费下载

相关推荐

上一篇:Anthropic 交互式提示工程教程(prompt-eng-interactive-tutorial)完整指南:从基础结构到复杂业务级 Prompt 的系统化实战
下一篇:抖音下载器:重构内容获取体验的技术方案

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询