R包开发基本步骤(下)

作者: Shaoqian_Ma | 来源:发表于2020-05-06 17:56 被阅读0次

参考:R package: https://r-pkgs.org/index.html
接着上一次的文章:R包开发基本步骤(上)

Step4

Edit DESCRIPTION

我们可以看到上次的warning里面,有提到关于license和document的问题:

  • Non-standard license specification
  • Undocumented code objects: 'fbind'

这是因为我们没有对函数进行任何说明,也没有声明包的作者、许可等信息

Make these edits:

  • Make yourself the author.
  • Write some descriptive text in the Title and Description fields.

直接在Rstudio里打开Description文件,编辑成像下面的样子:

Package: foofactors
Title: Make Factors Less Aggravating
Version: 0.0.0.9000
Authors@R:
    person("Jane", "Doe", email = "jane@example.com", role = c("aut", "cre"))
Description: Factors have driven people to extreme measures, like ordering
    custom conference ribbons and laptop stickers to express how HELLNO we
    feel about stringsAsFactors. And yet, sometimes you need them. Can they
    be made less maddening? Let's find out.
License: What license it uses
Encoding: UTF-8
LazyData: true

use_mit_license()

这里用的是MIT的license,需要在Description中写好,然后用use_mit_license进行声明

use_mit_license("Jane Doe")
#> ✔ Setting License field in DESCRIPTION to 'MIT + file LICENSE'
#> ✔ Writing 'LICENSE.md'
#> ✔ Adding '^LICENSE\\.md$' to '.Rbuildignore'
#> ✔ Writing 'LICENSE'

这时目录下多了一个LICENSE文件

打开license文件,确认里面的信息:

YEAR: 2019
COPYRIGHT HOLDER: Jane Doe

document()

平常需要查某个函数的帮助文档时就是用help,如果我们也希望自己的函数可以通过help调出帮助文档呢?这里需要对函数添加document,这些document都放在man文件夹下

package called roxygen2 handle the creation of man/fbind.Rd

打开fbind脚本,把光标插入函数里任意地方,然后点击 Code > Insert roxygen skeleton,编辑如下:

#' Bind two factors
#'
#' Create a new factor from two existing factors, where the new factor's levels
#' are the union of the levels of the input factors.
#'
#' @param a factor
#' @param b factor
#'
#' @return factor
#' @export
#' @examples
#' fbind(iris$Species[c(1, 51, 101)], PlantGrowth$group[c(1, 11, 21)])

这还不够,注意要用document函数对我们添加的comment进行更新:

document()
#> Updating foofactors documentation
#> Updating roxygen version in /tmp/RtmpsJ87ir/foofactors/DESCRIPTION
#> Writing NAMESPACE
#> Loading foofactors
#> Writing NAMESPACE
#> Writing fbind.Rd

测试下:

?fbind

NAMESPACE changes

上一步document函数执行以后更新了NAMESPACE文件,像下面这样:

# Generated by roxygen2: do not edit by hand

export(fbind)

命名空间里的export声明了该函数可以通过library进行调用:

The export directive in NAMESPACE is what makes fbind() available to a user after attaching foofactors via library(foofactors). Just as it is entirely possible to author .Rd files “by hand”, you can manage NAMESPACE explicitly yourself. But we choose to delegate this to devtools (and roxygen2).

check() again

重新检查,发现原来的两个warning没有了:

check()
#> ── R CMD check results ───────────────────────── foofactors 0.0.0.9000 ────
#> Duration: 8.8s
#> 
#> 0 errors ✔ | 0 warnings ✔ | 0 notes ✔

Step5

install()

可以说我们现在有了一个最小最简单的完整的R包,可以通过install()下载到我们的library中了:

install()
   checking for file ‘/tmp/RtmpsJ87ir/foofactors/DESCRIPTION’ ...
✔  checking for file ‘/tmp/RtmpsJ87ir/foofactors/DESCRIPTION’
─  preparing ‘foofactors’:
   checking DESCRIPTION meta-information ...
✔  checking DESCRIPTION meta-information
─  checking for LF line-endings in source and make files and shell scripts
─  checking for empty or unneeded directories
─  building ‘foofactors_0.0.0.9000.tar.gz’
Running /home/travis/R-bin/lib/R/bin/R CMD INSTALL \
  /tmp/RtmpsJ87ir/foofactors_0.0.0.9000.tar.gz --install-tests 
* installing to library ‘/home/travis/R/Library’
* installing *source* package ‘foofactors’ ...
** using staged installation
** R
** byte-compile and prepare package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded from temporary location
** testing if installed package can be loaded from final location
** testing if installed package keeps a record of temporary installation path
* DONE (foofactors)

而且fbind函数可以正常使用:

library(foofactors)

a <- factor(c("character", "hits", "your", "eyeballs"))
b <- factor(c("but", "integer", "where it", "counts"))

fbind(a, b)
#> [1] character hits      your      eyeballs  but       integer   where it 
#> [8] counts   
#> Levels: but character counts eyeballs hits integer where it your

use_testthat()

先载入必要包:library(testthat)

接着上次写的fbind函数,我们希望可以对函数做更细节化的测试,可以用到use_testthat()这个函数,初始化一个test的环境:

use_testthat()
#> ✔ Adding 'testthat' to Suggests field in DESCRIPTION
#> ✔ Creating 'tests/testthat/'
#> ✔ Writing 'tests/testthat.R'
#> ● Call `use_test()` to initialize a basic test file and open it for editing.

接着,我们用use_test对具体的函数进行测试,这会生成新的tests目录和函数的测试文件:

use_test("fbind")
#> ✔ Increasing 'testthat' version to '>= 2.1.0' in DESCRIPTION
#> ✔ Writing 'tests/testthat/test-fbind.R'

在test-fbind.R这个文件里写入下列内容:

test_that("fbind() binds factor (or character)", {
  x <- c("a", "b")
  x_fact <- factor(x)
  y <- c("c", "d")
  z <- factor(c("a", "b", "c", "d"))

  expect_identical(fbind(x, y), z)
  expect_identical(fbind(x_fact, y), z)
})

这里就是为了测试一下fbind函数的输出结果是否和预期相符。

然后run一下:

test()
#> ✔ |  OK F W S | Context
#> 
⠏ |   0       | fbind
✔ |   2       | fbind
#> 
#> ══ Results ════════════════════════════════════════════════════════════════
#> OK:       2
#> Failed:   0
#> Warnings: 0
#> Skipped:  0

没有报错说明test结果是和预期相符的。

use_package()

注意我们写的函数可能需要用到其他包里的函数,哪怕是很常见的utils::head(),也是需要从其他包的命名空间里import的。如果没有import,在check的时候会有warning。

use_package("forcats")
#> ✔ Adding 'forcats' to Imports field in DESCRIPTION
#> ● Refer to functions with `forcats::fun()`

这时在DESCRIPTION文件里会出现Import forcats

然后我们再补充一个函数:

use_r("fcount")
#> ● Edit 'R/fcount.R'

添加如下:

#' Make a sorted frequency table for a factor
#'
#' @param x factor
#'
#' @return A tibble
#' @export
#' @examples
#' fcount(iris$Species)
fcount <- function(x) {
  forcats::fct_count(x, sort = TRUE)
}

load_all()在这里就是模拟一下包的下载安装过程

load_all()
#> Loading foofactors
fcount(iris$Species)
#> # A tibble: 3 x 2
#>   f              n
#>   <fct>      <int>
#> 1 setosa        50
#> 2 versicolor    50
#> 3 virginica     50

同样要更新帮助文档:

document()
#> Updating foofactors documentation
#> Writing NAMESPACE
#> Loading foofactors
#> Writing NAMESPACE
#> Writing fcount.Rd

use_github()

怎么把Rstudio的项目和Github关联起来呢?参考:

https://happygitwithr.com/new-github-first.html

use_readme_rmd()

如果你的R包已经在Github上了,那么一个完整的README.md文件将显得尤为重要,也就是每个R包的home page,记录了整个R包的完整信息

use_readme_rmd()函数初始化一个可执行的Rmarkdown文档待编辑:

use_readme_rmd()
#> ✔ Writing 'README.Rmd'
#> ✔ Adding '^README\\.Rmd$' to '.Rbuildignore'
#> ✔ Writing '.git/hooks/pre-commit'

功能是:

README.Rmd already has sections that:

  • Prompt you to describe the purpose of the package.
  • Provide code to install your package.
  • Prompt you to show a bit of usage.

完整的编辑内容示例如下:

---
output:
  md_document:
    variant: markdown_github
---

<!-- README.md is generated from README.Rmd. Please edit that file -->

```{r, echo = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.path = "README-"
)
```

**NOTE: This is a toy package created for expository purposes, for the second edition of [R Packages](https://r-pkgs.org). It is not meant to actually be useful. If you want a package for factor handling, please see [forcats](https://forcats.tidyverse.org).**

### foofactors

Factors are a very useful type of variable in R, but they can also be very aggravating. This package provides some helper functions for the care and feeding of factors.

### Installation

```{r installation, eval = FALSE}
devtools::install_github("jennybc/foofactors")
```
  
### Quick demo

Binding two factors via `fbind()`:

```{r}
library(foofactors)
a <- factor(c("character", "hits", "your", "eyeballs"))
b <- factor(c("but", "integer", "where it", "counts"))
```

Simply catenating two factors leads to a result that most don't expect.

```{r}
c(a, b)
```

The `fbind()` function glues two factors together and returns factor.

```{r}
fbind(a, b)
```

Often we want a table of frequencies for the levels of a factor. The base `table()` function returns an object of class `table`, which can be inconvenient for downstream work.

```{r}
set.seed(1234)
x <- factor(sample(letters[1:5], size = 100, replace = TRUE))
table(x)
```

The `fcount()` function returns a frequency table as a tibble with a column of factor levels and another of frequencies:

```{r}
fcount(x)
```

然后我们要制作README.md文件,需要执行这个Rmarkdown:

rmarkdown::render("README.Rmd") ## or use "Knit HTML" in RStudio

然后README.md就自动生成了。

The end: check() and install()

最终检查:

check()
#> ── R CMD check results ───────────────────────── foofactors 0.0.0.9000 ────
#> Duration: 9.6s
#> 
#> 0 errors ✔ | 0 warnings ✔ | 0 notes ✔

没有问题,那就可以安装使用了

install()

相关文章

  • R包开发基本步骤(下)

    参考:R package: https://r-pkgs.org/index.html接着上一次的文章:R包开发基...

  • R包开发基本步骤(上)

    参考:R package: https://r-pkgs.org/index.html 开发R包的过程中主要的R包...

  • R-编写R包-入门篇

    总结一下目前学习的,基于Rstudio的创建R包流程。 Part1:创建R包基本流程 step1:建立R包开发环境...

  • R包开发过程记录

    目的 走一遍R包开发过程,并发布到Github上使用。 步骤 1. 创建R包框架 Rsutdio ——> File...

  • 【r<-高级|实战】学习创建R包

    如果你想要的是快速构建R包骨架,推荐阅读在巨人的肩膀前行 催化R包开发进行学习;如果你想了解更为基本的R包创建知识...

  • 用Rstudio创建R包--感悟

    学R包请参考此链接:Rstudio 开发R包文档 其他文章:facebook-symbolsRstudio 开发R...

  • Spring框架的AOP技术(注解方式)

    步骤: 导入jar包 (后期可忽略) 先引入Spring框架开发的基本开发包 再引入Spring框架的AOP的开发...

  • 学习小组Day6笔记——R数据整理

    R包的使用 今日份学习是R包的基本操作,包括如何下载调用R包,dplyr的基本操作。mutate()select(...

  • 学习小组Day6笔记--kan

    笔记来自生信星球学习小组资料 Day6 学习内容-R包安装使用 1.思维导图镇楼 2.R包基本情况 由社区开发(d...

  • R包安装、加载与更新

    掌握了R基本的一些概念,今天咱们来简单了解下R包,R包安装、加载与更新 安装R包的几种方式 从CRAN中安装R包 ...

网友评论

    本文标题:R包开发基本步骤(下)

    本文链接:https://www.haomeiwen.com/subject/kfzwghtx.html