forked from hadley/adv-r
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Philosophy.rmd
96 lines (61 loc) · 5.8 KB
/
Philosophy.rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
---
title: Package development philosophy
layout: default
---
# Package development philosophy
This book espouses a particular philosophy of package development - it is not shared by all R developers, but it is one connected to a specific set of tools that makes package development as easy as possible.
There are three packages we will use extensively:
* `devtools`, which provides a set of R functions that makes package
development as easy as possible.
* `roxygen2`, which translates source code comments into R's official
documentation format
* `testthat`, which provides a friendly unit testing framework for R.
Other styles of package development don't use these packages, but in my experience they provide a useful trade off between speed and rigour. That's a theme that we'll see a lot in this chapter: base R provides rigorous tools that guarantee correctness, but tend to be slow. Sometimes you want to be able to iterate more rapidly and the tools we discuss will allow you to do so.
A package doesn't need to be complicated. You can start with a minimal subset of useful features and slowly build up over time. While there are strict requirements if you want to publish a package to the world on CRAN (and many of those requirements are useful even for your own packages), most packages won't end up on CRAN. Packages are really easy to create and use once you have the right set of tools.
Anytime you create some reusable set of functions you should put it in a package. It's the easiest path because packages come with conventions: you don't need to figure them out for yourself. You'll start with just your R code in the `R/` directory, and over time you can flesh it out with documentation (in `man/`), compiled code (in `src/`), data sets (in `data/`), and tests (in `inst/tests`).
## Getting started
To get started, make sure you have the latest version of R: if you want to submit your work to CRAN, you'll need to make sure you're running all checks with the latest R.
You can install the packages you need for this chapter with:
install.packages("devtools", dependencies = TRUE)
You'll also need to make sure you have the appropriate development tools installed:
* On Windows, download and install Rtools:
http://cran.r-project.org/bin/windows/Rtools/. This is not an R package.
* On Mac, make sure you have either XCode (free, available in the app store)
or the "Command Line Tools for Xcode" (needs a free apple id, available from
http://developer.apple.com/downloads)
* On Linux, make sure you've installed not only R, but the R development
devtools. This a Linux package called something like `r-base-dev`.
You can check you have everything installed and working by running this code:
library(devtools)
has_devel()
It will print out some compilation code (this is needed to help diagnose problems), but you're only interested in whether it returns `TRUE` (everything's ok) or an error (which you need to investigate further).
## Introduction to devtools
The goal of the devtools package is to make package development as painless as possible by encoding package building best practices in functions (so you don't have to remember or even know about them), and by minimising the iteration time when you're developing a package.
Most of the devtools functions we will use take a path to the package as their first argument. If the path is omitted, devtools will look in the current working directory - so for that reason, it's good practice to have your working directory set to the package directory.
The functions that you'll use most often are those that facilitate the [[package development cycle |development]]:
* `load_all()`: simulates package installation and loading by `source()`ing
all files in the `R/` directory, compiling and linking C, C++ and Fortran
files in the `src/` and `load()`ing data files in the `data/` directory.
More on that in [[package development |development]]
* `document()`: extracts documentation from source code comments and creates
`Rd` files in the `man/` directory. You can use `dev_help()` and
`dev_example()` instead of `help()` and `example()` to preview these files
without installing the package. More on that in [[documentation]].
* `test()`: runs all unit tests in the `inst/tests/` directory and reports the
results. More on that in [[testing]].
Other functions mimic standard R commands that you run from the command line:
* `build()` is equivalent to `R CMD build` and bundles package. See
[[package-basics]] for more about what a bundled package is.
* `install()` is equivalent to `R CMD INSTALL` and installs a package into a
local library. Learn more about the installation process in
[[package-basics]].
* `check()` is equivalent to `R CMD check`, and runs a large set of automated
tests against your package. Read more about checking as part of the
[[release]] process.
These tools should be more reliable than running the equivalent commands in the terminal (and much easier to use if you're not familiar with the terminal). They do more to ensure that command-line R is running in exactly the same way as your R GUI. They check that you're running the same version of R, with the same library paths, and with a standard collation order. These are things you don't need to worry about most of the time, but if they ever trip you up, it can take hours to figure out the source of the problem. `check()` and `install()` also run build first, which is recommended best practice.
There are two other functions that you use less commonly, only at the start and the end of package development:
* `create()` creates a new package, and fills it out with the basics (this is
the `devtools` equivalent of `package.skeleton`)
* `release()` checks the package, checks that you've done what the CRAN
maintainers expect, uploads to CRAN and drafts an email for the CRAN
maintainers