I'm trying to filter a time/position data series to produce a smoothed plot. I am measuring depth vs time (mechanical system) where the velocity is changing. I calculate velocity from the measured depth/time values and can plot velocity vs. depth, but at low speeds, the noise is excessive (for various reasons). The trend at low speeds is correct, but I'd like to be able to apply a filter that will use an adaptive smoothing routine, i.e. for low speeds (where I have many data points) I need to use a larger smoothing window, and for high speeds (few data points) I need to use a smaller window.
I've looked a bit and have figured out a solution using rollapply() but was wondering if there are other approaches. In particular, I'm not clear on how to "vectorise" an operation. I'm a relatively new coder so I'm sorry if my code is a bit amateurish. My solution is below:
adapt<-function(x,wmin,wmax) {
# adapt takes a vector of calculated velocities (x), a minimum window size (wmin),
# and a maximum window size (wmax). It returns a vector of filtered velocities
#
x<-ifelse(is.na(x),0,x) # check for na values
x<-ifelse(is.infinite(1/x),1/wmax,x) # check for infinite values
x<-runmed(x,11) # smooth raw velocities using 11 point window
wins<-ceiling(ifelse(is.infinite(1/x),wmin,1+wmax/(1+x)^15)) # set window widths
wins<-ifelse(wins<=wmin,wmin,wins) # set min windows
wins<-ifelse(wins>wmax,wmax,wins) # set max windows
out<-rollapply(x,width=wins,median) # apply filter to each element
out[length(x)]<-0 # set last value to zero
开发者_JS百科return(out)
}
精彩评论