-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtalk.Rnw
More file actions
352 lines (312 loc) · 10 KB
/
talk.Rnw
File metadata and controls
352 lines (312 loc) · 10 KB
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
\documentclass{beamer}
\usepackage{dtklogos}
\usepackage{url}
\usepackage{hyperref}
\mode<presentation>
{
\usetheme{JuanLesPins}
\setbeamercovered{invisible}
}
\begin{document}
<<resetpackage, cache=FALSE, echo=FALSE, warning=FALSE, include=FALSE>>=
unlink("age", recursive=TRUE)
@
<<setup, cache=FALSE, echo=FALSE, warning=FALSE, include=FALSE>>=
prefix = "talk"
# global chunk options
opts_chunk[["set"]](fig.path = paste0("figure/", prefix, "-"),
cache = FALSE,
dev = "pdf",
fig.align = "center",
tidy = FALSE,
size = 'footnotesize')
@
\title{Creating a package in R}
\subtitle{Using devtools and roxyen2}
\author{Brian Diggs}
\date{Portland R Users Group, August 22, 2012}
\maketitle
<<r-opts, echo=FALSE, include=FALSE, message=FALSE>>=
options(width = 50)
library("diagram")
library("devtools")
library("roxygen2")
@
\section{Motivation}
\label{sec:motivation}
% very important to use option [fragile] for frames containing code output!
\begin{frame}{Evolution of wanting to create a package}
\begin{itemize}
\item<1-> Write some code that solves a particular problem
\item<2-> Run into same problem again on another project; cut and paste code between projects
\item<3-> Same problem pops up a few more times; turn solution into
function, generalize it somewhat, put the code in a separate file,
\texttt{source} it
\item<4-> Colleague hears about your solution, wants to use it; send the
file, hopefully with some comments added as to how it works
\item<5-> Make some additional changes, maybe remember to update
comments, forget to send updated version to colleague, think there
must be a better way
\end{itemize}
\uncover<6->{
\begin{center}
\LARGE Package!
\end{center}
}
\end{frame}
\begin{frame}{Advantages of packages}
\begin{itemize}
\item Source code organization
\item Documentation
\item Code isolation
\item Testing infrastructure
\end{itemize}
\end{frame}
\begin{frame}{Aspects not covered}
\begin{itemize}
\item Source code control/version control
\item Compiled code in packages
\item Submission to CRAN
\item Internationalization
\item Package maintenance and updating
\end{itemize}
\end{frame}
\section{Terminology}
\begin{frame}
<<echo=FALSE, fig.width=7, fig.height=4>>=
par(mar = c(0,0,0,0))
openplotmat()
elpos <- coordinates(pos=c(1,1,2))
fromto <- matrix(ncol=2, byrow=TRUE, data=c(1,2,2,3,2,4))
nr <- nrow(fromto)
arrpos <- matrix(ncol=2, nrow=nr)
for (i in 1:nr)
arrpos[i,] <- straightarrow(to = elpos[fromto[i,2], ],
from = elpos[fromto[i, 1], ],
lwd = 2, arr.pos = 0.8, arr.length = 0.5)
textrect(elpos[1,], shadow.size=0, radx=0.2, rady=0.05, lab="Source directory")
textrect(elpos[2,], shadow.size=0, radx=0.2, rady=0.05, lab="Source package (.tar.gz)")
textrect(elpos[3,], shadow.size=0, radx=0.2, rady=0.05, lab="Windows binary package (.zip)")
textrect(elpos[4,], shadow.size=0, radx=0.2, rady=0.05, lab="Mac binary package (.tgz)")
textplain(arrpos[1,]+c(0,0.1), lab="R CMD build", adj=c(-0.1,0.5))
textplain((arrpos[2,] + arrpos[3,])/2 + c(0,0.05), lab="R CMD INSTALL --build")
@
\end{frame}
\section{Prerequisites}
\label{sec:prerequisites}
\begin{frame}[fragile]
\begin{itemize}
\item Linux/Unix-like
\begin{itemize}
\item \url{http://cran.r-project.org/doc/manuals/R-admin.html#Essential-and-useful-other-programs-under-a-Unix_002dalike}
\item Compilers
\item A {\LaTeX} distribution
\end{itemize}
\item Windows
\begin{itemize}
\item \url{http://cran.r-project.org/doc/manuals/R-admin.html#The-Windows-toolset}
\item Rtools
\url{http://cran.r-project.org/bin/windows/Rtools/}
\item {\MiKTeX}, a {\LaTeX} distribution \url{http://www.miktex.org/}
\end{itemize}
\item Mac OS X
\begin{itemize}
\item \url{http://cran.r-project.org/bin/macosx/RMacOSX-FAQ.html#What-is-needed-to-build-R}
\item Xcode from Apple
\item Fortran compiler \url{http://cran.r-project.org/bin/macosx/tools/}
\item Mac{\TeX}, a {\LaTeX} distribution \url{http://tug.org/mactex/}
\end{itemize}
\end{itemize}
\end{frame}
\section{Example function}
\begin{frame}[fragile]
<<>>=
source("age.at.R", echo=TRUE, prompt="", continue="",
max.deparse.length = Inf)
@
\end{frame}
\section{Format of source directory}
\begin{frame}
\begin{itemize}
\item Use \texttt{package.skeleton} to make the beginning of the package source
\begin{itemize}
\item from files (\texttt{code\_files} argument)
\item from objects in the environment (\texttt{list} argument, character
vector of object names)
\end{itemize}
\item This is done only once
\item Thereafter, edit the files in the new source directory
\end{itemize}
\end{frame}
\begin{frame}[fragile]
<<package.skeleton>>=
package.skeleton(name = "age",
code_files = "age.at.R",
path = ".")
@
\end{frame}
\begin{frame}[fragile]
<<>>=
list.files("age", recursive=TRUE)
@
\begin{itemize}
\item \texttt{DESCRIPTION} and \texttt{NAMESPACE} have specific formats
\item Source code is under \texttt{R}
\item Reference documentation is under \texttt{man}
\item Will add and describe more directories as we go along
\end{itemize}
\end{frame}
\section{Documentation}
\begin{frame}[Types]
\begin{itemize}
\item Reference documentation
\begin{itemize}
\item Required
\item Statically checked
\item \texttt{Rd} file format
\item in \texttt{man} directory
\item Accessible from within R by \texttt{help()}
\end{itemize}
\item Tutorial or other freeform documentation (vignettes)
\begin{itemize}
\item Optional
\item \texttt{Sweave} documents (\texttt{Rnw} source, PDF output)
\item in \texttt{vignette} directory; formerly in \texttt{inst/doc} directory
\item Accessible from within R by \texttt{vignette()}
\end{itemize}
\item Other
\begin{itemize}
\item Any format, PDF preferred
\item in \texttt{inst/doc} directory
\item Not directly accessible from within R
\end{itemize}
\end{itemize}
\end{frame}
\begin{frame}{\texttt{roxygen2} and \texttt{Rd} files}
\texttt{Rd} files document function by function
\begin{itemize}
\item Input parameters
\item Output
\item Short and long description
\end{itemize}
\texttt{roxygen2} allows this same information to be documented in the same
file as the function source code. The \texttt{Rd} file is then generated from
this specification.
\end{frame}
\begin{frame}[fragile]
<<echo=FALSE, highlight=FALSE, comment=NA>>=
cat(readLines("age.at.doc1.R"), sep="\n")
@
\end{frame}
\begin{frame}{Vignettes}
\begin{itemize}
\item Vignettes are \texttt{Sweave} (\texttt{Rnw}) files
\item Designed to dynamically use and display the results of the code in the package
\item Supplemented with a \texttt{\%\\VignetteIndexEntry\{\}} for indexing purposes
\end{itemize}
\end{frame}
\section{Code isolation (Namespaces)}
\begin{frame}[fragile]
\begin{itemize}
\item Specifies what is meant to be public versus private
\item Does not truly hide anything (can still be accessed)
\item Can specify which functions from other packages this package relies on
\item Also includes declaration of S3 generics and instances of S3 generics
\item This can also be handled by \texttt{roxygen2} so as to keep it with the
source code
\end{itemize}
<<echo=FALSE, highlight=FALSE, comment=NA>>=
cat(readLines("age.at.doc2.R"), sep="\n")
@
\end{frame}
\section{Testing infrastructure}
\begin{frame}
\begin{itemize}
\item Examples in documentation: part documentation, part testing
\begin{itemize}
\item Are run (by default) as part of package checking
\item Only tests that an error is not thrown
\item Can be run in an interactive session with \texttt{example()} to see output
\end{itemize}
\item Explicit tests
\begin{itemize}
\item In the \texttt{tests} directory
\item Can hook into testing suites such as the \texttt{testthat} package
\item Can be used to verify results of the examples
\end{itemize}
\item Vignettes act as a sort of test in that failure to build is not allowed
\end{itemize}
\end{frame}
\begin{frame}[fragile]
\frametitle{Examples}
<<echo=FALSE, highlight=FALSE, comment=NA>>=
cat(readLines("age.at.doc3.R"), sep="\n")
@
\end{frame}
\subsection{Integrating \texttt{testthat} infrastructure}
\begin{frame}[fragile]
\frametitle{\texttt{tests/test-all.R}}
<<echo=FALSE, highlight=FALSE, comment=NA>>=
cat(readLines("test-all.R"), sep="\n")
@
\end{frame}
\begin{frame}[fragile]
\frametitle{\texttt{inst/tests/test-age-at.R}}
<<echo=FALSE, highlight=FALSE, comment=NA>>=
cat(readLines("test-age-at.R"), sep="\n")
@
\end{frame}
<<echo=FALSE>>=
aaR <- readLines("age/R/age.at.R")
writeLines(c(readLines("age.at.doc1.R"),
readLines("age.at.doc2.R"),
readLines("age.at.doc3.R"),
aaR),
"age/R/age.at.R")
dir.create("age/tests")
dir.create("age/inst")
dir.create("age/inst/tests")
writeLines(readLines("test-all.R"),
"age/tests/test-all.R")
writeLines(readLines("test-age-at.R"),
"age/inst/tests/test-age-at.R")
unlink("age/Read-and-delete-me")
@
\section{Using \texttt{devtools}}
\begin{frame}[fragile]
Doing all these things, our package directory now looks like
<<>>=
list.files("age", recursive=TRUE)
@
\end{frame}
\begin{frame}[fragile]
\frametitle{Turning the package source into a source package}
<<>>=
document("age")
build("age")
file.exists("age_1.0.tar.gz")
@
\end{frame}
\begin{frame}[fragile]
\frametitle{Checking the package}
<<>>=
check("age")
@
\end{frame}
\section{References}
\label{sec:references}
\begin{frame}
\begin{itemize}
\item {\it Writing R Extensions}
\url{http://cran.r-project.org/doc/manuals/R-exts.html}
\item Hadley Wickham's \texttt{devtools} wiki
\url{https://github.com/hadley/devtools/wiki}
\end{itemize}
\end{frame}
\begin{frame}[fragile]
\frametitle{Session info}
<<results="asis">>=
toLatex(sessionInfo())
@
\end{frame}
\end{document}