简体中文 繁體中文 English Deutsch 한국 사람 بالعربية TÜRKÇE português คนไทย Français Japanese

站内搜索

搜索
AI 风月

活动公告

03-01 22:34
03-01 19:23
通知:本站资源由网友上传分享,如有违规等问题请到版务模块进行投诉,资源失效请在帖子内回复要求补档,会尽快处理!
10-23 09:31

如何构建R语言的软件包?

8

主题

128

科技点

60

积分

太初窥星

积分
60
发表于 2025-11-22 02:02:03 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x

R Packages 泛读笔记

分享一下本人阅读R Packages这本书所做的一点简单的笔记,说不定能帮到谁嘞。

原书籍在线阅读网站:https://r-pkgs.org/

基础流程

R包构建最基础流程:

  1. 编辑 R/ 文件
  2. document() 更新文档
  3. load_all() 加载更改
  4. 交互测试
  5. test() 运行测试
  6. check() 全面检查

存放数据

不同数据有不同存放方法。

数据类型 存放位置 适用场景 创建方法 特点
示例数据 data/ 给用户使用的数据 usethis::use_data() 用户可直接调用,需文档说明
内部数据 R/sysdata.rda 仅包内部使用的数据 usethis::use_data(internal=TRUE) 用户看不到,无需文档
原始文件 inst/extdata/ 需要保持原始格式的文件 手动复制文件 如图片、Excel等非R格式文件
临时数据 环境变量 运行时需要记录的状态 new.env(parent=emptyenv()) 只在当前R会话有效

R包重要目录如下。

目录 存放文件的类型 备注
src/ C/C++源代码 用于性能优化,需配合Rcpp或cpp11使用
inst/ 安装时要包含的额外文件 内容会被复制到安装包的根目录
tools/ 配置脚本和辅助工具 常用于维护脚本,可加入.Rbuildignore
demo/ 演示代码 已过时,如今须改用vignettes/
exec/ 可执行脚本 文件自动标记为可执行
po/ 国际化翻译文件 用于多语言支持

DESCRIPTION

DESCRIPTION 主要内容如下。

字段 作用 示例
Package 包名称(必填) Package: mypackage
Title 单行简短描述(首字母大写,无句号) Title: Data Analysis Tools for R
Description 详细描述(多行缩进,80字符/行) Description: Provides functions for cleaning and visualizing data.
Version 版本号(语义化版本,如 1.0.0 Version: 0.1.0
Authors@R 作者和维护者(推荐用 person() 函数) Authors@R: person("Jane", "Doe", email="jane@example.com", role=c("aut", "cre"))
License 许可证(如 MIT, GPL-3 License: MIT
Imports 必需依赖(安装时自动安装) Imports: dplyr (>= 1.0.0), tidyr
Suggests 可选依赖(测试/文档/扩展功能用) Suggests: testthat, ggplot2
Depends 仅用于声明R版本依赖(如 R (>= 4.0.0))或遗留包 Depends: R (>= 3.5.0)
URL 包官网/代码仓库链接(逗号分隔) URL: https://github.com/user/mypackage
BugReports 问题反馈链接(如GitHub Issues) BugReports: https://github.com/user/mypackage/issues
LazyData 延迟加载数据(设为 true 加速数据访问) LazyData: true
SystemRequirements 外部依赖(如C++库) SystemRequirements: C++11

依赖

若开发的R包必须和另一个包一起用,则要添加依赖。

  • Imports:核心功能必需的依赖
  • Suggests:可选功能/测试/文档的依赖
  • Depends:仅用于元包或强依赖场景

如下代码添加依赖:

# 核心依赖
usethis::use_package("dplyr", "Imports")

# 可选依赖
usethis::use_package("ggplot2", "Suggests")

执行后DESCRIPTION文件会自动生成:

Imports: 
    dplyr
Suggests: 
    ggplot2

另外在代码中还需显式声明使用了依赖函数,比如以dplyr::filter()举例如下:

clean_data <- function(data) {
  dplyr::filter(data, condition)  # 这里使用dplyr的filter
}

NAMESPACE

要更新NAMESPACE,运行devtools::document()。NAMESPACE文件相关操作:

操作 方案 生成NAMESPACE内容
声明用户可用的函数 #' @export export(function_name)
使用其他包的单个函数 #' @importFrom pkg function importFrom(pkg,function)
使用整个包 #' @import pkg (慎用) import(pkg)
S3方法 #' @exportS3Method S3method(generic,class)

许可证

许可证分为两种。

类型 特点 常见许可证 适用情况
Permissive 允许自由使用修改,只需保留原许可 MIT, Apache, BSD 希望代码被广泛使用
Copyleft 衍生作品必须使用相同许可 GPL, AGPL 希望保持代码开源

许可证相关核心文件有:

  • DESCRIPTION中的License字段
  • LICENSE文件(包含具体条款)
  • LICENSE.md(完整许可证副本,CRAN不上传)

常用以下代码生成对应许可证。

# 代码许可证
usethis::use_mit_license()    # 最宽松的MIT
usethis::use_gpl_license()    # 要求衍生作品开源

# 数据许可证
usethis::use_cc0_license()    # 数据完全开放
usethis::use_ccby_license()   # 要求署名

测试

test相关设置

# 首次设置测试环境
usethis::use_testthat(3)  # 使用testthat第3版

会创建:

  • tests/testthat/目录
  • DESCRIPTION中添加testthat依赖
  • tests/testthat.R入口文件

要创建对应脚本的测试文件,可用如下代码。

# 创建与R/foo.R对应的测试文件
usethis::use_test("foo")  # 生成tests/testthat/test-foo.R

测试用例基本结构:

test_that("描述测试内容", {
  # 准备测试数据
  test_data <- ...

  # 调用被测函数
  result <- your_function(test_data)

  # 验证结果
  expect_equal(result, expected_value)
  expect_true(is.numeric(result))
})

常用期望函数如下。

函数 用途 示例
expect_equal() 宽松相等性检查 expect_equal(10, 10 + 1e-7)
expect_identical() 严格相等性检查 expect_identical(10, 10L)
expect_error() 验证错误 expect_error(1/"a")
expect_warning() 验证警告 expect_warning(log(-1))
expect_snapshot() 快照测试 expect_snapshot(print(obj))

禁止在测试文件中显式调用 library(testthat),因为 testthat 的依赖版本应通过 DESCRIPTION 文件声明(如 Suggests: testthat (>= 3.0.0)),而非在测试代码中硬编码,确保所有测试均使用同一版本。

roxygen

roxygen2 是 R 语言中用于自动化生成函数文档的工具。开发者直接在函数代码上方用特殊格式的注释(以 #' 开头)编写文档,然后通过 devtools::document() 自动生成 .Rd 文件(R 的官方文档格式)。支其编写支持 Markdown语法。

roxygen2 注释块格式:

#' 函数的标题(首句,简短描述)
#'
#' 函数的详细描述(可多段)。
#' 使用Markdown语法(如 `code`、*强调*、[链接]())。
#'
#' @param 参数名 参数说明(类型、用途、默认值等)。
#' @returns 返回值说明(类型、结构)。
#' @examples 
#' 可执行的R代码示例(需自包含、无副作用)。
#' @export  # 标记为导出函数(公开给用户)
my_function <- function(x, y) {
  函数体
}

示例:

#' Add together two numbers
#' 
#' @param x A number.
#' @param y A number.
#' @returns A numeric vector.
#' @examples
#' add(1, 1)
#' add(10, 1)
add <- function(x, y) {
  x + y
}

关键标签如下:

标签 用途 注意事项
@param 描述函数参数。如 @param x A numeric vector. 同类参数可合并:@param x,y Numeric vectors.
@returns 说明返回值。如 @returns A logical vector of same length as input. CRAN要求所有导出函数必须明确返回值。
@examples 提供可运行的示例代码。 必须无错误、快速(<10秒)、无副作用(比如不修改全局选项)。
@export 将函数导出到NAMESPACE,允许用户调用。 未导出的函数用 @noRd 标记。
@inheritParams 复用其他函数的参数文档。如 @inheritParams other_function 避免重复描述相同参数。
@section 添加带标题的详细说明块。如 @section Warning: Do not input NULL. 适用于复杂函数的额外说明。

Vignettes

Vignettes是R包的长篇教程,用于展示核心功能。可通过browseVignettes("包名")vignette("名称", package="包名")查看。

初始化Vignette:

usethis::use_vignette("my-vignette")  # 创建模板文件`vignettes/my-vignette.Rmd`

这样就能:

  • 自动生成vignettes/目录。
  • DESCRIPTION中添加依赖(如knitrrmarkdown)。

Vignettes默认开头如下,采取YAML格式,其中>表示下方均为文本。

---
title: "Vignette Title"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Vignette Title}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

README

README文件是用户接触包的第一站,需要有三个核心要素:

  1. 为什么使用这个包(介绍)?
  2. 如何快速上手(教程)?
  3. 如何安装(CRAN/GitHub)?:

使用README.Rmd生成README.md

usethis::use_readme_rmd()  # 创建模板
devtools::build_readme()    # 渲染更新

NEWS

NEWS文件记录版本变更。结构如下:

# foofy (development version)

* Better error message when grooving an invalid grobble (#206).

# foofy 1.0.0

## Major changes

* Can now work with all grooveable grobbles!

## Minor improvements and bug fixes

* Printing scrobbles no longer errors (@githubusername, #100).

* Wibbles are now 55% less jibbly (#200).

建设R包网站

初始化配置:

usethis::use_pkgdown()       # 创建配置文件_pkgdown.yml
pkgdown::build_site()        # 首次构建网站

usethis::use_pkgdown_github_pages()  #GitHub用户一键配置

pkgdown会自动整合以下内容生成网站:

文档类型 网站位置 生成源
函数文档 /reference/ man/*.Rd文件
数据集文档 /reference/ R/data.R中的文档
Vignettes /articles/下拉菜单 vignettes/*.Rmd
README 首页 README.Rmd
NEWS "News"导航栏 NEWS.md

添加logo步骤如下:

  1. 将logo图片保存为man/figures/logo.png
  2. 使用命令

    usethis::use_logo("path/to/your_logo.png") 

这样一来,logo图片会自动调整尺寸并更新README显示,且网站导航栏会自动显示logo。

只要.github/workflows/pkgdown.yaml包含下列代码,每次git push后便会自动重建网站。

on: 
  push: 
    branches: [main]
(ᗜᴗᗜ)
回复

使用道具 举报

0

主题

1099

科技点

585

积分

候风辨气

积分
585
发表于 2025-11-22 17:56:33 | 显示全部楼层
感謝分享
温馨提示:看帖回帖是一种美德,您的每一次发帖、回帖都是对论坛最大的支持,谢谢! [这是默认签名,点我更换签名]
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

手机版|联系我们|小黑屋|TG频道|RSS |网站地图

Powered by Pixtech

© 2025-2026 Pixtech Team.

>