- Hadley Wickham's Books
- Rcpp
- Debugging
- Rmarkdown
January 26, 2015
Rcpprmarkdown and knitrroxygen2)Things to make your life easier:
devtools
roxygen2
NAMESPACE file, generates documentation from source codetestthat
knitr
# Get packages
install.packages(c("devtools", "roxygen2", "testthat", "knitr"))
# Check that everything is installed and functioning
devtools::has_devel()
# Create your package
devtools::create('path/to/myPackage')
That was easy.
create() Create?DESCRIPTION
myPackage.Rproj
NAMESPACE
roxygen2 ensures you don't have to edit this by handR/
src/
inst/
inst/CITATION: how the package should be citedinst/python, inst/ruby, etc.data/
devtools::use_data()roxygen2 (see Hadley's R Packages )tests/
devtools::use_testthat()roxygen2#' Update Bins for ASH estimator
#'
#' @param bin Object returned from \code{ash::bin1}
#' @param newdata Vector of new data
#'
#' @example inst/examples/ash_example.R
#'
#' @export
updateBin1 <- function(bin, newdata) { ...
roxygen2::roxygenize() or devtools::document() to build documentationroxygen2 Block Produce?% Generated by roxygen2 (4.1.0): do not edit by hand
% Please edit documentation in R/ash.R
\name{updateBin1}
\alias{updateBin1}
\title{Update Bins for ASH estimator}
\usage{
updateBin1(bin, newdata)
}
\arguments{
\item{bin}{Object returned from \code{ash::bin1}}
\item{newdata}{Vector of new data}
}
\description{
Update Bins for ASH estimator
}
\examples{
# Create two batches of data
y1 <- rnorm(100)
y2 <- rnorm(100)
# Create bins from the batch 1
mybin <- ash::bin1(y1, ab=c(-5, 5), nbin=50)
# Get ASH estimate and plot it
myash <- ash::ash1(mybin, m=5)
plot(myash, type="l")
# Update the bins with batch 2
mybin <- online::updateBin1(mybin, y2)
# update ASH estimate and plot it
myash <- ash::ash1(mybin, m=5)
plot(myash, type="l")
}
roxygen2 Block Produce?devtoolsdevtools::install_github()
- Main argument is repo: accepts form username/repo[/subdir][@ref|#pull]
runr)# Get old release of devtools (Mac and Linux)
# For windows, see ?build_github_devtools
devtools::install_github("hadley/devtools@v1.6.1")
# Get latest release
devtools::install_github("hadley/devtools")
install_bitbucket, install_svn, install_git, install_url, install_version, install_local
source: xkcd
+, *, -, /, pow, <, <=, >, >=, ==, !=, !.floor(), cos(), gamma(), exp(), etc.r/d/p/q for all standard distributionsapply familyRcpp:
install.packages('Rcpp')A working C++ compiler:
sudo apt-get install r-base-devlibrary(Rcpp)
evalCpp("1+1")
## [1] 2
cppFunction function compiles C++ code and constructs an R wrapperlibrary(Rcpp)
cppFunction('
int addTwo(int x, int y) {
int sum = x + y;
return sum;
}
')
addTwo(1, 2)
## [1] 3
addTwo
## function (x, y)
## .Primitive(".Call")(<pointer: 0x107943f50>, x, y)
addTwo(1.9, 2.9)
## [1] 3
double, int, String, boolNumericVector, IntegerVector, CharacterVector, LogicalVectorNumericMatrix, IntegerMatrix, CharacterMatrix, LogicalMatrixList, DataFrame, Function, RobjectChange output and inputs to double
cppFunction('
double addTwo(double x, double y) {
double sum = x + y;
return sum;
}
')
addTwo(1.9, 2.9)
## [1] 4.8
for (init; condition; increment)sumR <- function(x) {
n <- length(x)
total <- 0
for(i in 1:n) {
total <- total + x[i]
}
return(total)
}
cppFunction('
double sumC(NumericVector x) {
int n = x.size();
double total = 0;
for(int i = 0; i < n; ++i) {
total += x[i];
}
return total;
}
')
library(microbenchmark) x <- runif(100000) microbenchmark( sum(x), sumR(x), sumC(x) )
## Unit: microseconds ## expr min lq mean median uq max neval ## sum(x) 92.389 92.826 105.5395 94.5465 117.5525 198.901 100 ## sumR(x) 35038.670 36697.757 38855.6528 37385.2430 38169.9185 71635.789 100 ## sumC(x) 88.438 89.823 108.7193 100.6170 119.4515 213.851 100
NumericMatrixA(i, j)cppFunction('
NumericMatrix diagC(NumericVector x) {
int n = x.size();
NumericMatrix mat(n, n);
for (int i = 0; i < n; i++) {
mat(i, i) = x[i];
}
return mat;
}
')
diag() Functionmicrobenchmark( diag(1:1000), diagC(1:1000) )
## Unit: milliseconds ## expr min lq mean median uq max neval ## diag(1:1000) 2.790997 2.821166 3.893509 2.856402 2.899913 37.579529 100 ## diagC(1:1000) 2.798069 2.825595 2.877935 2.864132 2.911366 3.084649 100
Your .cpp file needs to start with
#include <Rcpp.h>using namespace Rcpp;
and include the Rcpp attribute
// [[Rcpp::export]]
above any function you wish to be called from R.
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
int timesTwo(int x) {
return x * 2;
}
/*** R
# test my function
timesTwo(5)
*/
// [[Rcpp::plugins(openmp)]])BH
[[Rcpp::depends(BH)]] in sourceboost/math Library// We can now use the BH package
// [[Rcpp::depends(BH)]]
#include <Rcpp.h>
#include <boost/math/common_factor.hpp>
using namespace Rcpp;
// [[Rcpp::export]]
int computeGCD(int a, int b) {
return boost::math::gcd(a, b);
}
// [[Rcpp::export]]
int computeLCM(int a, int b) {
return boost::math::lcm(a, b);
}
sourceCpp("examples/boost.cpp")
computeGCD(100, 75)
## [1] 25
computeLCM(77, 55)
## [1] 385
curl -O http://r.research.att.com/libs/gfortran-4.8.2-darwin13.tar.bz2sudo tar fvxz gfortran-4.8.2-darwin13.tar.bz2 -C /What if I want to use the Armadillo package for an inline function?
cppFunction("
arma::mat outerC(arma::colvec a, arma::rowvec b) {
return a*b;
}
", depends="RcppArmadillo")
outerC(1:3, 1:3)
## [,1] [,2] [,3] ## [1,] 1 2 3 ## [2,] 2 4 6 ## [3,] 3 6 9
#include <RcppArmadillo.h>// [[Rcpp::depends(RcppArmadillo)]]#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
// [[Rcpp::export]]
arma::mat outerC2(arma::colvec a, arma::rowvec b) {
return a*b;
}
/*** R
outerC2(1:2, 1:2)
*/
outer Functionsx <- 1:100 y <- 2:101 microbenchmark( x %*% t(y), tcrossprod(x, y), outer(x, y), outerC(x, y), outerC2(x, y), times=500)
## Unit: microseconds ## expr min lq mean median uq max neval ## x %*% t(y) 19.732 21.6235 35.64684 24.5695 35.6925 2204.709 500 ## tcrossprod(x, y) 14.583 15.9000 43.76020 19.3800 25.1895 3157.459 500 ## outer(x, y) 24.997 28.7700 50.63866 32.7280 50.8855 2714.753 500 ## outerC(x, y) 22.646 28.0510 57.28111 34.5680 46.1335 1805.597 500 ## outerC2(x, y) 23.055 28.0570 57.90161 34.5795 49.0270 2547.162 500
devtools::use_rcpp()
src/ folder for .cpp filesR/#' @useDynLib your-package-name #' @importFrom Rcpp sourceCpp NULL
roxygen2 tags like //` @exportdevtools::load_all()traceback()
browser()
traceback() and browser()
lineprof package
devtools::install_github("hadley/lineprof")library(lineprof)
f <- function() {
pause(0.1)
g()
h()
}
g <- function() {
pause(0.1)
h()
}
h <- function() {
pause(0.1)
}
l <- lineprof(f()) l
## Reducing depth to 2 (from 5) ## Common path: <text>
## time alloc release dups ref src ## 1 0.080 0.001 0 1 <text>#3 f/pause ## 2 0.161 0.002 0 0 <text>#4 f/g ## 3 0.080 0.000 0 0 <text>#5 f/h
focus(l, "g")
## Reducing depth to 2 (from 4) ## Common path: <text>
## time alloc release dups ref src ## 1 0.080 0.001 0 0 <text>#8 g/pause ## 2 0.081 0.001 0 0 <text>#9 g/h
$y = x^2$$$y = x^2$$
source: http://rmarkdown.rstudio.com/
knitr Language Enginesrunr, and moreknitr is not limited to markdown