-
-
Notifications
You must be signed in to change notification settings - Fork 102
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rolling trimmed mean #132
Comments
also, not sure if this should be a standalone function in R, or just add a I think that one way to think about this is that there are just variants of a single function, with |
If I may join the discussion; I think having it as a |
it seems to me that the place to put this would be in trim in
so your prototype functionality would deliver the median of the data for any value of |
agree this should ideally just extend runMean runTrimmedMean <- function(x, n, cumulative = FALSE, trim = 0) {
if (trim <= 0) return(runMean(x, n = n, cumulative = cumulative))
if (trim >= 0.5) return(runMedian(x, n = n, cumulative = cumulative))
x <- try.xts(x, error = as.matrix)
if (NCOL(x) > 1) stop("ncol(x) > 1. runSum only supports univariate 'x'")
len.x <- nrow(x)
r <- rep(NA_real_, len.x)
v <- as.vector(x)
start <- max(last(which(is.na(v))) + 1, 1)
if (len.x >= (start + n)) {
trim.start <- floor(trim * n) + 1
trimmed.range <- trim.start:(n + 1 - trim.start)
i <- start + n - 1
buff <- sort(v[start:i])
r[i] <- sum(buff[trimmed.range]) / length(trimmed.range)
while(i < len.x) {
i <- i+1
if (cumulative) {
#expand buffer
n <- n + 1
trim.start <- floor(trim * n) + 1
trimmed.range <- trim.start:(n + 1 - trim.start)
} else {
#remove old value from buffer. will always get found by match, so no need for error handling
buff <- buff[-match(v[i-n], buff)]
}
#add new value to buffer. match + insertion is faster than resorting whole buffer
after <- match(TRUE, v[i] <= buff, nomatch = length(buff) + 1) - 1
buff <- append(buff, v[i], after = after) # < 1 will pre-pend
r[i] <- sum(buff[trimmed.range]) / length(trimmed.range) #na's already handled, so bypass checks in mean
}
}
return(reclass(r, x))
} |
Great start! Would it make sense to have unit tests of this function versus something like |
yes. thats exactly how i tested this version. ill formalize them, as i need to that anyways |
Awesome. You can use 'tinytest' (it's a near drop-in replacement for 'testthat') instead of 'RUnit'. I intend to convert all the TTR tests to 'tinytest' at some point. |
Description
new functionality supporting rolling trimmed means
when
trim * n
is not an integer, there is special handling needed for the boundaries:https://stats.stackexchange.com/questions/4252/how-to-calculate-the-truncated-or-trimmed-mean
very hokey rough implementation.
The text was updated successfully, but these errors were encountered: