I am new to R and having trouble fitting a Lowpass filter to my data. I am measuring Force
exerted on a treadmil over a period of 30 seconds
with a sample rate of 250/s or 250Hz
.
The data contains negative force values as seen in this image
This is due to ripples in the signal or background noise. I need to be able to filter out any force signal <0
, and for this I have used the Butter
function within the Signal
package:
ritLowPass = function(s, frqCutOff, bPlot = F )
{
f = butter( 4, frqCutOff/(smpRate/2), "low" ); # lowpass filter
s.lp = rev( filter( f, rev( filter( f, s ))) );
if( bPlot ) {
idx=(1*smpRate):(4*smpRate);
plot( x=idx/smpRate, y=s[idx], xlab="time/s", ylab="signal", ty="l" );
lines( x=idx/smpRate, y=s.lp[idx], col="red", lwd=2)
}
return(data.frame(s.lp));
}
VT_filter <- ritLowPass(guest$Fz, 250, bPlot)
sample data:
Time Fz
0 3.769
0.004 -32.94
0.008 -117.305
0.012 -142.329
0.016 -55.35
0.02 -27.362
0.024 29.039
0.028 73.718
0.032 76.633
0.036 4.482
0.04 -80.949
0.044 -114.279
0.048 -102.968
0.052 -9.76
0.056 35.405
0.06 152.541
0.064 79.249
0.068 50.147
0.072 22.547
0.076 47.757
0.08 -29.123
0.084 57.384
0.088 88.715
0.092 195.115
0.096 118.752
0.1 183.22
0.104 157.957
0.108 37.992
0.112 -7.893
When I run the code I get the following error:
VT_filter <- ritLowPass(guest$Fz, 250, bPlot)
Error in butter.default(4, frqCutOff/(smpRate/2), "low") :
butter: critical frequencies must be in (0 1)
Called from: butter.default(4, frqCutOff/(smpRate/2), "low")
I wonder if I should be using HighPass instead or is there another option for attenuating any force signal lower than zero?
Preamble
I'm not sure I can see anything in the data that suggests your "culprit" frequency is 250 Hz, or that you should cut frequencies above this value.
If you're trying to remove signal noise at a specific frequency, you'll need to find the noise frequency first.
spectrum
is your friend.However, assuming you actually want to filter frequencies above 250 Hz:
Short Answer
If you want to filter frequencies above 250 Hz, your sampling frequency needs to be at least 500 Hz.
Long Answer
Your filter can only filter between frequencies of 0 and the Nyquist frequency, i.e. 0 to (Sampling Frequency)/2. This is a hard limit of information theory, not an implementation issue.
You're asking it to filter something that is twice the Nyquist Frequency.
help(butter)
gives the following about theW
parameter:The cutoff value you are trying to assign to the filter is (250)/(250/2) = 2. The function is telling you this is outside its capabilities (or the capabilities of any digital filter).