Skip to content

Instantly share code, notes, and snippets.

@jmackie
Created December 7, 2015 12:23
Show Gist options
  • Save jmackie/2d67d78579b483aa09c8 to your computer and use it in GitHub Desktop.
Save jmackie/2d67d78579b483aa09c8 to your computer and use it in GitHub Desktop.
Rolling average for non-uniform time-sampled data.
##################################################################
# A rolling average function for non-uniform time-sampled data. #
##################################################################
# Create some awkward time sampled data.
time <- cumsum(round(runif(1000, 0, 2), 2))
x <- runif(1000, 300, 400)
df <- data.frame(t = time, x)
# Rcpp, otherwise R would take all day...
library(Rcpp)
cppFunction('std::vector<double> roll_nunif(NumericVector x, NumericVector t, double window) {
double n = x.size(), sum, len, tmp;
std::vector<double> out(n); // Return vector.
// Find first index.
int start = 0; while (t[start] < window) ++start;
for (int i = start; i < n; ++i)
{
sum = 0; len = 0; // Reset.
tmp = i;
while(t[tmp] > (t[i] - window)) // Work backwards.
{
sum += x[tmp]; ++len;
// Stop if we hit the bottom of x.
if ((tmp - 1) < 0)
break;
else
--tmp;
}
out[i] = sum / len;
}
return out;
}
')
# 30 second rolling average:
df$roll <- roll_nunif(df$x, df$t, window = 30)
# Test ----------------------------------------------
# Pick a random timestamp...
r <- sample(seq_along(df$t), 1)
# Chop off the top...
tmp <- df[1:r, ]
# Chop off the bottom...
tmp <- tmp[tmp$t > (df$t[r] - 30), ]
x1 <- mean(tmp$x)
x2 <- tmp$roll[nrow(tmp)]
if (x1 == x2) print("Booyah.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment