Rolling means (in C++)
The vectorized rolling mean function, rollmean3()
had good performance but very poor readability. It's really hard to tell that this code calculates a rolling mean, which makes the function harder to debug and to maintain.
The second version, rollmean2()
, was slower but easier to read. If we translate this into C++, hopefully, we'll get easy readability and fast performance.
rollmean2()
is defined in your workspace; you can print its definition to remind yourself how it works. You will now translate rollmean2()
to C++, assigning to rollmean4()
.
This exercise is part of the course
Optimizing R Code with Rcpp
Exercise instructions
- Set
res
as aNumericVector
with lengthn
and values given by theNumericVector
'sget_na()
method. - Calculate
total
as the firstwindow
values ofx
. - Calculate the mean at
window - 1
as the total divided by the width of the window. - In the second loop, update the total by subtracting the
i - window
th element ofx
and adding thei
th element ofx
.
Hands-on interactive exercise
Have a go at this exercise by completing this sample code.
#include
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector rollmean4(NumericVector x, int window) {
int n = x.size();
// Set res as a NumericVector of NAs with length n
NumericVector res(___, ___::___());
// Sum the first window worth of values of x
double total = 0.0;
for(int i = 0; i < window; i++) {
total += ___;
}
// Treat the first case seperately
res[window - 1] = ___ / window;
// Iteratively update the total and recalculate the mean
for(int i = window; i < n; i++) {
// Remove the (i - window)th case, and add the ith case
total += - ___ + ___;
// Calculate the mean at the ith position
res[i] = total / window;
}
return res;
}
/*** R
# Compare rollmean2, rollmean3 and rollmean4
set.seed(42)
x <- rnorm(1e4)
microbenchmark(
rollmean2(x, 4),
rollmean3(x, 4),
rollmean4(x, 4),
times = 5
)
*/