全书目录 / 第 0 章
00
起步与环境
R 已经不是"能不能进制药"的问题,而是"你什么时候进场"的问题。本章把环境、心智与验证框架一次搭好。
0.1 R 已经走进监管递交
先放下"R 只是探索工具"的旧印象。三条已发生的事实:
- R Consortium Submissions Working Group 完成了 Pilot 1–5:用 R 包形式向 FDA 递交分析并通过审评复现(见 Pilot 1 记录 与 五轮 Pilot 经验总结)。
- 2025-08 FDA eCTD 技术一致性指南更新:新增接受
.rds / .rdata / .rda / .md / .rd等格式,扩展.zip / .html(可直接递交完整 R 包),见 R Consortium 公告。 - 企业级成功案例:J&J 以"SAS 做 ADaM + R 做 TFL"的混合策略完成 FDA 递交并获批,见 案例复盘;PharmaSUG 2026 最佳论文级工作 ET-279《Goodbye SAS, Hello R: Practical Workflows for CDISC》 给出了 R 的 CDISC 全流程。
对你的含义:SAS 技能(CDISC 语义、SAP 理解、QC 纪律)在 R 世界里同样值钱,甚至更值钱——因为 R 生态缺的正是懂监管语境的人。
测验 1:2025-08 FDA eCTD 指南更新后,下列哪组文件形式被新增/扩展接受?
选 B。此次更新让非公开 R 包可直接以 .zip 递交,.html 交互报告也在扩展之列;此前 Pilot 阶段需借助 pkglite 转纯文本束。
0.2 安装与验证:先让 R 听话
本书所有输出捕获自下面这套环境。若你机器上已有 R(例如 C:\Program Files\R\R-4.5.0),无需重装;只需确认版本 ≥ 4.3 并配置一个快的 CRAN 镜像。
# 终端验证安装
Rscript --version
# R 会话内查看环境与已附包
si <- sessionInfo()
cat('R version:', R.version.string, '\n')
cat('Platform:', R.version$platform, '\n')
# 配置 CRAN 镜像(国内推荐清华源),写入 ~/.Rprofile 可持久化
options(repos = c(CRAN = "https://mirrors.tuna.tsinghua.edu.cn/CRAN/"))
# 实跑捕获(R 4.5.0,Windows) Rscript (R) version 4.5.0 (2025-04-11) R version: R version 4.5.0 (2025-04-11 ucrt) Platform: x86_64-w64-mingw32 Attached base: stats, graphics, grDevices, utils, datasets, methods, base
逐行解读:
Rscript --version:命令行入口,等价于 SAS 的sas -version;批处理跑脚本就靠它。sessionInfo():你的"PROC LOG 首页"——R 版本、平台、已加载包及版本,QC 与递交复现的第一证据。options(repos=...):换镜像源,类比 SAS 的 mirror 配置;清华源在国内下载二进制包快一个量级。
0.3 用 renv 把项目锁起来
SAS 环境由公司统一维护;R 的包生态是去中心的,环境 reproducibility 是你自己的责任。renv 为每个项目建独立库并生成 renv.lock 锁文件——这就是递交材料里"Set-up R environment"附录的底稿。
# 在项目目录初始化(bare = 先建空库,不扫描依赖)
renv::init(bare = TRUE)
# 记录当前依赖到 renv.lock
renv::snapshot()
# 换一台机器/同事复现:按锁文件装回完全相同的版本
renv::restore(prompt = FALSE)
# 实跑捕获(节选) The following package(s) will be updated in the lockfile: # CRAN ----------------------------------------------------------------------- - renv [* -> 1.1.5] The version of R recorded in the lockfile will be updated: - R [* -> 4.5.0] - Lockfile written to ".../renv.lock". --- restore --- - The library is already synchronized with the lockfile.
逐行解读:
init(bare=TRUE):只建项目私库与骨架,不自动扫描装包——干净起步,依赖由你显式添加。snapshot():把"当前项目库用了哪些包、什么版本"写进 renv.lock;相当于冻结 PROC 版本清单。restore():读锁文件装回同版本;"already synchronized" 说明当前库已与锁文件一致。
测验 2:renv 在监管语境下最核心的价值是什么?
选 C。renv.lock 是环境复现的证据链一环(J&J 案例的 ADRG 附录即以此为基础);代码版本仍由 Git 管理,二者互补。
0.4 项目目录约定
study_x/ ├── study_x.Rproj # RStudio 项目文件(打开即切到项目库) ├── renv.lock # 环境锁 ├── spec/ # 映射与表格规格(sdtm_spec.xlsx, tfl_spec.xlsx) ├── R/ # 可复用函数(derive_*.R) ├── programs/ # 主程序(sdtm_01_dm.R, adam_02_adsl.R, tfl_03_t1.R) ├── data/ # 原始数据(只读!) ├── outputs/ # ADaM / TLF 产物 ├── logs/ # 运行日志(message/logger 落盘) └── tests/ # testthat 单元与比对测试
SAS 误区:把 data/ 当 work 库随手写回。R 项目里原始数据必须只读;所有派生产物进 outputs/,否则 QC 与审计追踪无从谈起。
0.5 SAS ↔ R 概念映射表
这张表是全书的"翻译词典",遇到陌生 R 代码先回这里找锚点:
| SAS | R 对应 | 备注 |
|---|---|---|
| DATA step 行级处理 | dplyr::mutate() / base transform | R 是列向量思维,避免逐行循环 |
| merge / PROC SQL join | dplyr::left_join() 等 | 注意 NA 键不匹配(SAS 缺失键行为不同) |
| retain + 条件赋值 | mutate(x = accumulate(...)) 或 cumsum() | purrr::accumulate 最贴近 retain 心智 |
| lag() | dplyr::lag()(配合 order_by()) | R 的 lag 无队列陷阱,但需先排序 |
| PROC SORT | arrange() / base::order() | by 组内排序用 arrange(grp, var) |
| PROC MEANS class | summarise(.by = grp, ...) | .by 是 dplyr 1.1+ 的分组语法 |
| PROC FREQ tables | table() / gtsummary::tbl_summary() | 出报告级频数表用 gtsummary |
| PROC TRANSPOSE | tidyr::pivot_wider()/pivot_longer() | 名字即意图,比 transpose 可读 |
| ODS RTF/PDF | Quarto + flextable / rtables 导出 | 见第 4 章 |
| macro + %put 日志 | function() + logger::log_info() | 函数有词法作用域,不再全局污染 |
0.6 GxP / CSV 验证心智平移
验证对象变了,验证纪律没变:
| SAS 世界 | R 世界 |
|---|---|
| 验证安装好的 SAS + 标准宏库 | 验证 CRAN/内部包(valtools 工作流,见第 5 章)+ renv 锁环境 |
| 双编程 + PROC COMPARE | 双编程 + diffdf::diffdf() / arsenal::compare()(见第 2 章) |
| 日志审阅(ERROR/WARNING 计数) | message/warning 捕获 + testthat 断言 + CI 全绿 |
| 程序头注释规范 | roxygen 文档 + Git commit 规范 + spec 链接 |
PharmaSUG 2026 ET-140 给出了 R 包验证框架的完整思路,是第 5 章 5.8 节的底稿;现在先记住结论:在 R 世界,验证的最小单元是"包 + 测试 + 锁环境",而不是单个脚本。
0.7 本站用法与复现指南
- 代码块:右上角"复制"按钮取原文;高亮为运行时完成,复制得到的是纯净源码。
- 输出块(虚线边框):标注"实跑捕获"的为 R 4.5.0 真实输出;标注"示例输出(节选)"的为教学节选。
- 测验:点选项即判分并展开解析;章末不再另给答案。
- 案例复现:
Rscript cases/c1_sdtm_adam_t1.R即可重跑;网络案例首次运行会缓存到cases/cache/,断网时可复现。 - 暗色/进度:右上 ◐ 切换主题;顶部细线为阅读进度。
章末资源
- R for Data Science (2e) — 全书主线教材,免费在线;ch1–ch4 对应本书第 1 章 入门
- Posit Cheatsheets — dplyr/tidyr/ggplot2 速查,打印贴墙 参考
- PharmaSUG 2026 ET-279 Goodbye SAS, Hello R — R 的 CDISC 全流程实战论文 进阶
- R/Pharma 会议 — 制药 R 社区年度会议与 Summit 圆桌笔记 参考
- 本地精读:
../PharmaR/Pharma开源社区近2年文章精读与AI影响分析.md— 近 2 年生态主线与 AI 影响 参考
本章练习
- (易)在本机跑通 0.2 全部命令,把 sessionInfo 输出存成 txt 留档。
- (中)建一个 renv 项目,装入 dplyr 后 snapshot,删除库目录再 restore,体会锁文件作用。
- (难)对照 0.5 映射表,挑你最近一个 SAS 程序,写出等价的 R 伪代码骨架(不必跑通)。
下一章:把 SAS 用户的语言直觉逐条翻译成 R——向量、factor、NA 与三大编程范式。