Skip to contents

Apply signal filtering to vector data with either: 1. A cubic smoothing spline. 2. A Butterworth digital filter. 3. A simple moving average.

Usage

filter_data(
  x,
  method = c("smooth-spline", "butterworth", "moving-average"),
  type = c("low", "high", "stop", "pass"),
  spar = NULL,
  n = 1,
  W,
  critical_frequency,
  sample_rate,
  width,
  verbose
)

Arguments

x

A numeric vector.

method

Indicates how to filter the data (see Details).

"smooth-spline"

fits a cubic smoothing spline.

"butterworth"

uses a centred Butterworth digital filter. type should be defined (see Details).

"moving-average"

uses a centred moving average filter.

type

Specify the filter type. Only relevant for method = "butterworth" (see Details).

"low"

For a low-pass filter (default).

"high"

For a high-pass filter.

"stop"

For a stop-band (band-reject) filter.

"pass"

For a pass-band filter.

spar

A numeric scalar defining the smoothing parameter for method = "smooth-spline".

n

An integer scalar defining the order of a Butterworth filter for method = "butterworth".

W

A numeric scalar or two-element vector defining the fractional critical frequency(ies) of a Butterworth filter for method = "butterworth".

critical_frequency

A numeric scalar or two-element vector defining the critical frequency(ies) of a Butterworth filter for method = "butterworth".

sample_rate

A numeric scalar for the sample rate in Hz for method = "butterworth".

width

A numeric scalar defining the window length of samples for method = "moving-average".

verbose

A logical. TRUE (the default) will return warnings and messages which can be used for troubleshooting. FALSE will silence these messages. Errors will always be returned.

Value

A numeric vector of filtered data.

Details

method = "smooth-spline"

applies a non-parametric cubic smoothing spline from stats::smooth.spline(). Smoothing is defined by the parameter spar, which can be left blank and automatically determined via penalised log liklihood. This usually works well for smoothing responses occurring on the order of minutes or longer. Or spar can be defined explicitly, typically (but not necessarily) in the range spar = [0, 1].

method = "butterworth"

applies a centred (two-pass symmetrical) Butterworth digital filter from signal::butter() and signal::filtfilt(). The filter order is defined by n, typically in the range n = [1, 10]. Higher filter orders tend to better capture rapid changes in amplitude, but also cause more distortion artefacts in the signal. General advice is to use the lowest order which sufficiently captures any rapid step-changes in the data.

Filter type defines how the desired signal frequencies are either passed through or rejected from the output signal. Low-pass and high-pass filters allow only frequencies lower or higher than the critical frequency W to be passed through as the output signal, respectively. Stop-band defines a critical range of frequencies which are rejected from the output signal. Pass-band defines a critical range of frequencies which are passed through as the output signal.

The critical (cutoff) frequency is defined by W, a numeric scalar for low-pass and high-pass filters, or a two-element vector c(low, high) defining the lower and upper bands for stop-band and pass-band filters. W represents the desired fractional critical frequency in the range W = [0, 1], where 1 is the Nyquist frequency, i.e., half the sample rate of the data in Hz.

Alternatively, the critical frequency can be defined by critical_frequency and sample_rate together. critical_frequency represents the desired critical frequency in Hz, and sample_rate is the sample rate of the recorded data in Hz. W = critical_frequency / (sample_rate/2).

Defining both critical_frequency and sample_rate explicitly will overwrite W.

method = "moving-average"

applies a centred (two-way symmetrical) moving average filter from zoo::rollapply(). The moving-average is calculated over a window of width width defining the number of samples between [i - floor(width/2), i + floor(width/2)]. A partial moving- average will be calculated at the edges of the existing data.

Examples

set.seed(13)
n <- 500
x <- seq(0, 2*pi, len = n)
y_clean <- 2*sin(x)
noise <- rnorm(n, mean = 0, sd = 0.5)
y <- y_clean + noise

y.spline <- filter_data(y, method = "smooth-spline")
#>  `smooth.spline()` `spar` set to 0.861829231501579
y.LP <- filter_data(y, method = "butterworth", n = 2, W = 0.05)
y.MA <- filter_data(y, method = "moving-average", width = 30)

if (FALSE) { # \dontrun{
plot(x, y)
lines(x, y.spline, lwd = 2, col = "blue")
lines(x, y.LP, lwd = 2, col = "red")
lines(x, y.MA, lwd = 2, col = "green4")
} # }