creating r packages - meetupfiles.meetup.com/1685538/rpackages.pdf · creating r packages rory...

50
Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating R Packages Rory Winston February 17, 2011 Rory Winston Melbourne R User Group Creating R Packages

Upload: others

Post on 07-Aug-2020

5 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Creating R Packages

Rory Winston

February 17, 2011

Rory Winston Melbourne R User Group

Creating R Packages

Page 2: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

1 Outline

2 Basics

3 Creating a Simple Package

4 Interfacing With Native Code

Rory Winston Melbourne R User Group

Creating R Packages

Page 3: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

R Packages

R’s ”jewel in the crown”

Almost 3,000 packages on CRAN

Preferred extension mechanism for R

Rory Winston Melbourne R User Group

Creating R Packages

Page 4: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Why create a Package?

Keep frequently-used code and data together

Save repetitive typing and analysis

Extend base R functionality

Share analysis with others

Package reproducible research

Rory Winston Melbourne R User Group

Creating R Packages

Page 5: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Package Conventions

R follows ”convention over configuration”

Flexible packaging structure

Sensible defaults

Some pedantry: Note that ’package’ and ’library’ are notstrictly equivalent

Rory Winston Melbourne R User Group

Creating R Packages

Page 6: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Package Structure

Basic package structure

mypackage/

DESCRIPTION # Mandatory package metadata

R/ # R source files

data/ # Data directory

demo/ # Demo code

man/ # Package docs (.Rd)

po/ # i18n

src/ # Native (compiled) code

tests/ # Unit tests

Rory Winston Melbourne R User Group

Creating R Packages

Page 7: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Default Loaded Packages

Not all packages are loaded by default

A basic subset only

Loading many packages can aversely affect performance

To see packages loaded by default:

> getOption("defaultPackages")

[1] "datasets" "utils" "grDevices"

[4] "graphics" "stats" "methods"

Rory Winston Melbourne R User Group

Creating R Packages

Page 8: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Installed Packages

> pkginfo <- installed.packages()

> class(pkginfo)

[1] "matrix"

> dimnames(pkginfo)[1]

[[1]]

[1] "base" "boot" "class"

[4] "cluster" "codetools" "datasets"

[7] "faraway" "foreign" "graphics"

[10] "grDevices" "grid" "KernSmooth"

[13] "lattice" "MASS" "Matrix"

[16] "matrixexp" "methods" "mgcv"

[19] "nlme" "nnet" "Rcpp"

[22] "rpart" "spatial" "splines"

[25] "stats" "stats4" "survival"

[28] "tcltk" "tools" "utils"

[31] "zoo"

Rory Winston Melbourne R User Group

Creating R Packages

Page 9: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Installed Packages

> dimnames(pkginfo)[2]

[[1]]

[1] "Package" "LibPath" "Version"

[4] "Priority" "Depends" "Imports"

[7] "LinkingTo" "Suggests" "Enhances"

[10] "OS_type" "License" "Archs"

[13] "Built"

Rory Winston Melbourne R User Group

Creating R Packages

Page 10: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Currently Loaded Packages

To see currently loaded packages:

> (.packages())

[1] "stats" "graphics" "grDevices"

[4] "utils" "datasets" "methods"

[7] "base"

Rory Winston Melbourne R User Group

Creating R Packages

Page 11: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Simple Package Example

Australian Lotto package

Some sample data (historical results)

Simple functions

Help files

Building and checking the package

Rory Winston Melbourne R User Group

Creating R Packages

Page 12: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Creating the Package

Simplest way to create a package in R:

Create a basic set of functions and data

Use package.skeleton()

Modify and add as required

Rory Winston Melbourne R User Group

Creating R Packages

Page 13: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

The ozlotto Package

Let’s download some sample data for our package:$ curl

https://www.tattersalls.com.au/FullResults/TattslottoResults.zip

> lotto.zip

$ unzip lotto.zip

Rory Winston Melbourne R User Group

Creating R Packages

Page 14: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Load The Data

Load the data into R:

> lotto<-read.table("Tattslotto.txt", sep = ",",

+ fill = TRUE, header = TRUE,

+ col.names = c("number", "date",

+ c(1:6), "supp1", "supp2"),

+ na.strings=c("-"))

> lotto$date <- as.POSIXct(strptime(lotto$date,

+ "%Y%m%d"))

> head(lotto,4)

number date X1 X2 X3 X4 X5 X6 supp1 supp2

1 101 1981-03-07 33 8 15 20 25 5 11 NA

2 102 1981-03-14 1 32 18 19 37 38 4 NA

3 103 1981-03-21 20 12 17 1 19 39 2 NA

4 104 1981-03-28 34 14 2 18 26 15 4 NA

Rory Winston Melbourne R User Group

Creating R Packages

Page 15: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Some Data

> draws <- as.data.frame(lotto[,3:8])

> colnames(draws) <- paste("draw", c(1:6))

> head(draws, 5)

draw 1 draw 2 draw 3 draw 4 draw 5 draw 6

1 33 8 15 20 25 5

2 1 32 18 19 37 38

3 20 12 17 1 19 39

4 34 14 2 18 26 15

5 14 29 7 18 2 16

Rory Winston Melbourne R User Group

Creating R Packages

Page 16: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Some Functions

> plot.freqs <- function(x) barplot(cex.names=.6,

+ table(unlist(x)), col="lightblue",

+ las=2, main="Total Draw Frequency")

> plot.freqs(draws)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

Total Draw Frequency

0

50

100

150

200

Rory Winston Melbourne R User Group

Creating R Packages

Page 17: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

What’s In The Environment?

> sapply(objects(), function(x) (class(get(x))))

draws lotto plot.freqs

"data.frame" "data.frame" "function"

Rory Winston Melbourne R User Group

Creating R Packages

Page 18: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Creating The Package Skeleton

> package.skeleton(list=ls(), name="lotto")

Creating directories ...

Creating DESCRIPTION ...

Creating Read-and-delete-me ...

Saving functions and data ...

Making help files ...

Done.

Further steps are described in './lotto/Read-and-delete-me'.

Rory Winston Melbourne R User Group

Creating R Packages

Page 19: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

What’s In The Package?

lotto/

|~data/

| |-draws.rda

| |-lotto.rda

|~man/

| |-draws.Rd

| |-lotto-package.Rd

| |-lotto.Rd

| |-plot.freqs.Rd

|~R/

| |-plot.freqs.R

|-DESCRIPTION

|-Read-and-delete-me

Rory Winston Melbourne R User Group

Creating R Packages

Page 20: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Editing the DESCRIPTION

Mandatory file (very important!)

”Debian Control File” format

Many different fields, see docs for reference

Dependencies (and licenses) can use version ranges

Rory Winston Melbourne R User Group

Creating R Packages

Page 21: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Example DESCRIPTION

Package: lotto

Type: Package

Title: OzLotto Example Package

Version: 1.0

Date: 2011-02-14

Author: Rory Winston

Maintainer: Rory Winston <[email protected]>

Description: Simple toy package

Depends: R (>= 2.12.0)

License: GPL (>=2) | BSD

LazyLoad: yes

Rory Winston Melbourne R User Group

Creating R Packages

Page 22: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Package Dependencies

If your package depends on functionality defined in otherpackages

This can be added to the Depends section

Package versions can also be specified

Example from the highlight package:

Depends: R (>= 2.11.0), tools, codetools, utils, parser (>= 0.0-10)

Rory Winston Melbourne R User Group

Creating R Packages

Page 23: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

.RData Files

Data files are stored in .rda format

This is a portable, (optionally) compressed representation

Same as save(lotto, file="lotto.rda")

$ file lotto.rda

lotto.rda: gzip compressed data

Rory Winston Melbourne R User Group

Creating R Packages

Page 24: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Help Files - The .Rd Format

Rd is the ”R documentation format”

Can be compiled into

LATEX;PDF;HTML;ASCII text;HTML Help;etc.

Functions and data can be documented;

Uses a TEX-like markup

Many, many options

Rory Winston Melbourne R User Group

Creating R Packages

Page 25: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Sample Documentation for a Function

\name{plot.freqs}

\alias{plot.freqs}

\title{Plotting Number Frequencies Across Draws}

\description{

This function produces a bar plot of number

frequencies across all six-number draws.

}

\usage{plot.freqs(x)}

\arguments{\item{x}{

A \code{data.frame} where each row corresponds

to a separate lottery draw and the columns

represent the numbers drawn in that event, in order.}}

\author{Rory Winston}

\seealso{

See \code{\link{draws}}

Also see \code{\link[graphics]{hist}}

}

\examples{

random.draw <- function() sapply(45:(45-6),

function(x) sample(1:x, 1))

draws <- t(replicate(random.draw(), n=1000))

plot.freqs( draws )

}

Rory Winston Melbourne R User Group

Creating R Packages

Page 26: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Documenting Data

Note that R will generate doc skeletons for package data

The data will be inspected and sample docs created

For example:

\format{

A data frame with 1620 observations on the following 10 variables.

\describe{

\item{\code{number}}{a numeric vector}

\item{\code{date}}{a POSIXct}

\item{\code{X1}}{a numeric vector}

\item{\code{X2}}{a numeric vector}

\item{\code{X3}}{a numeric vector}

\item{\code{X4}}{a numeric vector}

\item{\code{X5}}{a numeric vector}

\item{\code{X6}}{a numeric vector}

\item{\code{supp1}}{a numeric vector}

\item{\code{supp2}}{a numeric vector}

}

}

Rory Winston Melbourne R User Group

Creating R Packages

Page 27: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Sample Generated Manual

Package ‘lotto’February 15, 2011

Type Package

Title OzLotto Example Package

Version 1.0

Date 2011-02-14

Author Rory Winston

Maintainer Rory Winston <[email protected]>

Description Simple toy package

Depends R (>= 2.12.0)

License GPL (>=2) | BSD

LazyLoad yes

R topics documented:lotto-package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1draws . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2lotto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3plot.freqs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

Index 5

lotto-package Simple Oz Lotto Package

Description

This package contains some historical result data and some simple functions.

Details

Package: lottoType: PackageVersion: 1.0Date: 2011-02-14License: UnlimitedLazyLoad: yes

1

Rory Winston Melbourne R User Group

Creating R Packages

Page 28: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Math in Rd Docs

Note that Rd supports TEX-like math markup

The math markup will be downgraded to ASCII whereappropriate

The text \deqn{p(x) = \frac{1}{b-a}} becomes (inPDF and console):

lotto 3

lotto Historical Oz Lotto Results

Usage

data(lotto)

Format

A data frame with 1620 observations on the following 10 variables.

number a numeric vector

date a POSIXct

X1 a numeric vector

X2 a numeric vector

X3 a numeric vector

X4 a numeric vector

X5 a numeric vector

X6 a numeric vector

supp1 a numeric vector

supp2 a numeric vector

Examples

data(lotto)## maybe str(lotto) ; plot(lotto) ...

plot.freqs Plotting Number Frequencies Across Draws

Description

This function produces a bar plot of number frequencies across all six-number draws. The uniformdistribution is commonly notated as

p(x) =1

b − a

Usage

plot.freqs(x)

Arguments

x A data.frame where each row corresponds to a separate lottery draw and thecolumns represent the numbers drawn in that event, in order.This function produces a bar plot of number frequencies across all

six-number draws. The uniform distribution is commonly notated as

p(x) = \frac{1}{b-a}

Rory Winston Melbourne R User Group

Creating R Packages

Page 29: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

R CMD check

R CMD check is the first port of call

Checks documentation, package structure, runs examples

Produces compiled documentation (e.g. PDF) ifappropriate

Basic procedure:

Run R CMD check <packagename>

Check errors in generated <packagename>.Rcheck dirIf any errors, fix uprinse and repeat

Rory Winston Melbourne R User Group

Creating R Packages

Page 30: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Testing The Package

The package can be loaded from a working directoryinstance, if we are in the generated lotto.Rcheck dir:

> library(lib.loc=".", package="lotto")

As R CMD check generates a loadable package

Rory Winston Melbourne R User Group

Creating R Packages

Page 31: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Building The Package

A binary package can be built using R CMD build

-binary <packagename>

This will build a .zip on Windows, tarballs on *nix

This can be installed to a local library

> install.packages(c("lotto_1.0.tar.gz"),

repos=NULL)

This can then be loaded as normal: > library(lotto)

Rory Winston Melbourne R User Group

Creating R Packages

Page 32: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Things To Be Aware Of

Namespaces

Lazy Loading

What does the following mean:

> suppressWarnings(dump("AirPassengers",

+ "", evaluate=FALSE))

AirPassengers <-

<promise: lazyLoadDBfetch(c(0L, 367L), datafile, compressed,

envhook)>

Rory Winston Melbourne R User Group

Creating R Packages

Page 33: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Interfacing With Native Code

Why go native?

SpeedFunctionality otherwise unavailable

Some examples:

Algorithms in C/C++/Fortran code

Speeding up slow R routines

Workarounds for R limitations (e.g. shared memory)

Rory Winston Melbourne R User Group

Creating R Packages

Page 34: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Considerations When Using R and C

The R/native code learning curve is steep

R uses many LISP idioms in the C codee.g. PROTECT(ans =

FirstArg(CAR(sub),CADR(sub)));

R itself has many LISP-like features

> (`+`(`sum`(`^`((`:`(1,10)),2)),

+ (`^`((`sum`(`:`(1,10))),2))))

[1] 3410

> sum((1:10)^2) + (sum(1:10))^2

[1] 3410

Garbage collection is also an issue

Frequent source of error (even for the R team)

Rory Winston Melbourne R User Group

Creating R Packages

Page 35: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Simple Example

R does not have a ’matrix exponentiation’ operator

Scalar power only(x11 x12x21 x22

)n

≡(

xn11 xn12xn21 xn22

)> X <- matrix(1:4, 2, 2)

> X^2

[,1] [,2]

[1,] 1 9

[2,] 4 16

> X %*% X

[,1] [,2]

[1,] 7 15

[2,] 10 22

Rory Winston Melbourne R User Group

Creating R Packages

Page 36: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Creating a New Operator

All operators in R are just functions

Binary operators take two arguments

We will create a new operator %^%

Rory Winston Melbourne R User Group

Creating R Packages

Page 37: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

The Exponentiation Operator

> `%^%` <- function(X, a) {

+ stopifnot(is.matrix(X))

+ a <- as.integer(a)

+ if (a==0) diag(nrow(X))

+ if (a==1) X

+

+ x <- X

+ for (i in 2:a)

+ X <- X %*% x

+ X

+ }

> X %^% 2

[,1] [,2]

[1,] 7 15

[2,] 10 22

Rory Winston Melbourne R User Group

Creating R Packages

Page 38: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Adding Native Code

Now let’s add a native code version

We can create a new package called matrixexp

We will create a single file, matrixexp.c

This will contain a C function called matexp

This will perform the calculations and return the result toR

Rory Winston Melbourne R User Group

Creating R Packages

Page 39: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

The C Implementation

#include <R.h>

#include <Rdefines.h>

#include <Rinternals.h>

...

SEXP matexp(SEXP matrix, SEXP power)

{

int nrows, ncols;

SEXP x;

x = coerceVector(matrix, REALSXP);

dims = getAttrib(x, R_DimSymbol);

nrows = INTEGER(dims)[0];

ncols = INTEGER(dims)[1];

if (nrows != ncols)

error(_("can only raise square matrix to power"));

if (!isNumeric(power))

error(_("exponent must be a scalar integer"));

...Rory Winston Melbourne R User Group

Creating R Packages

Page 40: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

The C Implementation

...

if (e < -1)

error(_("exponent must be >= -1"));

else if (e == 1)

return x;

else if (e == -1) { /* return matrix inverse via solve() */

SEXP call= PROTECT( lang2( install( "solve.default"), x ) );

SEXP inv = PROTECT( eval( call, R_GlobalEnv ) );

UNPROTECT(2);

return inv;

}

...

Rory Winston Melbourne R User Group

Creating R Packages

Page 41: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

The C Implementation

...

for (i = 0; i < ncols*nrows; i++)

REAL(matrix)[i] = ((i % (ncols+1) == 0) ? 1 : 0);

if (e == 0) {; // return identity matrix }

else

while (e > 0) {

if (e & 1) {

// perform matrix multiply

e--;

}

// perform matrix multiply

e >>= 1;

}

..

return matrix;

Rory Winston Melbourne R User Group

Creating R Packages

Page 42: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Compiling the Code

We can just compile the native code using:

R cmd SHLIB <source files>

Example: R CMD SHLIB matrixexp.c

(Native code is also built by R CMD check)

This produces a shared lib (.DLL on Windows, .so on *nix)

Rory Winston Melbourne R User Group

Creating R Packages

Page 43: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Bridging between R and C

To allow us to access R code from C, we need to use oneof the predefined calling conventions

In this case, we will use the .Call mechanism

Let’s redefine the %^% operator to use native code instead:

> `%^%` <- function(X, a) .Call("matexp",

+ X, a)

Rory Winston Melbourne R User Group

Creating R Packages

Page 44: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

The final step

The final step is to have our DLL be automatically loadedwhen the package is loaded

One way of doing this is the following:

Create a file called zzz.R

In the file, override the .First.lib() function to loadour DLL:

.First.lib <- function(lib,pkg) {

library.dynam("matrixexp", pkg, lib)

}

Rory Winston Melbourne R User Group

Creating R Packages

Page 45: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Package Structure

matrixexp/

|man/

|R/

| -zzz.R

|src/

| |-matrixexp.c

|-DESCRIPTION

Rory Winston Melbourne R User Group

Creating R Packages

Page 46: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Example

> install.packages(repos=NULL, "matrixexp_1.0.zip")

package 'matrixexp' successfully unpacked and MD5 sums checked

> library(matrixexp)

> `%^%` <- function(X,a) .Call("matexp", X, a)

> x <- matrix(1:4, 2, 2)

> x %^% 2

[,1] [,2]

[1,] 7 15

[2,] 10 22

Rory Winston Melbourne R User Group

Creating R Packages

Page 47: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

A Better Way (At Least For C++)

R/C(++) integration can be quite difficult

There is an easier way

Use the Rcpp package

Lots of examples

Clean, ”modern” C++

Manages memory allocation/protection

Provides nice syntatic sugar for C++ operations

Lots of examples of integration

see http://cran.r-project.org/web/packages/

Rcpp/index.html

Rory Winston Melbourne R User Group

Creating R Packages

Page 48: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Building Windows Packages

R is reasonably Unix-centric

Perl no longer required for most tasks

Some tools support (e.g. LATEX) also assumed

Packages can be compiled with Visual Studio

The mingw compiler and other supporting tools can bedownloaded from:

http://www.murdoch-sutherland.com/Rtools/

Rory Winston Melbourne R User Group

Creating R Packages

Page 49: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Further Reading

R CMD <command> -help

The R documentation

Mailing Lists

Anything by Pat Burns (http://www.burns-stat.com/)

Rory Winston Melbourne R User Group

Creating R Packages

Page 50: Creating R Packages - Meetupfiles.meetup.com/1685538/Rpackages.pdf · Creating R Packages Rory Winston Outline Basics Creating a Simple Package Interfacing With Native Code Creating

Creating RPackages

Rory Winston

Outline

Basics

Creating aSimplePackage

InterfacingWith NativeCode

Thank You

Rory Winston Melbourne R User Group

Creating R Packages