生物信息学从零开始学生物信息学与算法

R包开发基本步骤(下)

2020-05-06  本文已影响0人  Shaoqian_Ma

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

Step4

Edit DESCRIPTION

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

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

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:

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

---
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()
上一篇 下一篇

猜你喜欢

热点阅读