Zhiguang Huo (Caleb)
Wednesday September 30, 2020
Rcpp: for Seamless R and C++ Integration.
Prerequisites:
cppFunction() allows you to write C++ functions in R.
## Getting started with C++
library(Rcpp)
cppFunction('int add(int x, int y) {
int sum = x + y;
return sum;
}')
# add works like a regular R function
add
## function (x, y)
## .Call(<pointer: 0x10aef6a10>, x, y)
## [1] 5
## [1] 1
## [1] 1
cppFunction('int signC(int x) {
if (x > 0) {
return 1;
} else if (x == 0) {
return 0;
} else {
return -1;
}
}')
## [1] -1
## [1] -1
## user system elapsed
## 0.009 0.000 0.009
## user system elapsed
## 0.009 0.000 0.010
## user system elapsed
## 0.292 0.001 0.293
cppFunction('NumericVector pdistC(double x, NumericVector ys) {
int n = ys.size();
NumericVector out(n);
for(int i = 0; i < n; ++i) {
out[i] = sqrt(pow(ys[i] - x, 2.0));
}
return out;
}')
## [1] 2 1 0 1 2
## [1] 2 1 0 1 2
cppFunction('NumericVector rowSumsC(NumericMatrix x) {
int nrow = x.nrow(), ncol = x.ncol();
NumericVector out(nrow);
for (int i = 0; i < nrow; i++) {
double total = 0;
for (int j = 0; j < ncol; j++) {
total += x(i, j);
}
out[i] = total;
}
return out;
}')
## [1] 446 514 480 514 352 627 525 586 572 434
## [1] 446 514 480 514 352 627 525 586 572 434
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
double meanC(NumericVector x) {
int n = x.size();
double total = 0;
for(int i = 0; i < n; ++i) {
total += x[i];
}
return total/n;
}
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
double mpe(List mod) {
if (!mod.inherits("lm")) stop("Input must be a linear model");
NumericVector resid = as<NumericVector>(mod["residuals"]);
NumericVector fitted = as<NumericVector>(mod["fitted.values"]);
int n = resid.size();
double err = 0;
for(int i = 0; i < n; ++i) {
err += resid[i] / (fitted[i] + resid[i]);
}
return err / n;
}
Also refer to https://caleb-huo.github.io/teaching/2020FALL/lectures/week5_RPackage/Rpackage.html for regular steps
If your package name is GatorCPP
WD <- "~/Desktop"
setwd(WD)
usethis::create_package("GatorCPP") ## create the package
setwd(file.path(WD, "GatorCPP")) ## get into the package
devtools::document() ## need to do this, otherwise the next step use_rcpp won't work
usethis::use_rcpp() ## intialize rcpp
## put in R code in R and cpp code in src
Rcpp::compileAttributes() ## will generate a RcppExports.R
# devtools::load_all() ## this step seems not necessary this year
devtools::document() ## generate documentation
devtools::install() ## install the package
## use the package
library(GatorCPP)
#?meanRC
meanRC(1:10)