设置R频率为50 Hz且没有相位失真的低通滤波器?

时间:2018-08-16 12:32:03

标签: r lowpass-filter

我以500 Hz的采样频率收集了眼动数据。我已经计算了眼动的速度,现在我想对速度剖面应用一个50 Hz的低通滤波器(就像其他研究人员一样,例如Jainta,Hoormann和Jaschinski(2007))。

我正在努力在R中设置50 Hz低通滤波器。我尝试使用封装信号。

据我了解,当使用采样频率为500 Hz的巴特沃斯滤波器时,必须使用W = 0.2才能获得50 Hz的低通滤波器。以下正确吗?

bf <- butter(n = 1, w = 0.2, type = "low", plane = "z") 
y_filtered <- filter(bf, y)

但是,这将导致相位失真,例如,在此帖子中显示:

How do I run a high pass or low pass filter on data points in R?

同样根据链接文章中的答案,当使用函数filtfilt以避免相位失真时,我将不得不使用W = 0.4来实现50 Hz的低通滤波器。那是对的吗?

但是,由于filtfilt的文档中有“ ...,因此该功能尚需做一些工作-处于2000年版本的Octave代码状态。”如果有其他选择,我不想使用它。

我考虑过使用黄土,但是不确定,哪个跨度相当于一个50 Hz的滤波器?根据链接的视频,跨度设置为数据点总数的一部分。在R中也是如此吗?

https://www.youtube.com/watch?v=Vf7oJ6z2LCc

这对我来说意味着什么,我该如何选择跨度?

也许还有其他我最好使用的功能,到目前为止我还不知道...

那么,有人可以帮助我设置50 Hz低通滤波器吗?任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

如果信号不是超长信号(例如数百万个样本),那么简单的FFT滤波器就可以很好地完成工作。

首先是一些示例数据

set.seed(1)

sf <- 500   # sampling frequency
ns <- 2000  # number of samples
cf <- 50    # cut-off frequency

f1 <- 43
f2 <- 50
f3 <- 55
f4 <- 81

s1 <- sin(seq(0, pi*2*(ns/sf)*f1, length.out=ns))
s2 <- sin(seq(0, pi*2*(ns/sf)*f2, length.out=ns) + pi/4)
s3 <- sin(seq(0, pi*2*(ns/sf)*f3, length.out=ns) + pi/3)
s4 <- sin(seq(0, pi*2*(ns/sf)*f4, length.out=ns))
n1 <- runif(ns, -0.2, 0.2) + runif(ns, -0.2, 0.2)

xx.o <- ts(s1 + s2, frequency=sf)
xx <- ts((xx.o + s3 + s4 + n1/10)/4, frequency=sf)

xx.o <- (xx.o - mean(xx.o))/2
xx <- xx - mean(xx)

然后我们进行傅立叶变换,将上面的bin设为零,然后通过逆傅立叶变换进行重组。

ft <- fft(xx)
lft <- length(ft)
b <- ns/(sf/cf)
ft[-c(1:b, (lft-b):lft)] <- 0

xx.lp <- Re(fft(ft, inv=TRUE))/lft

par(mfrow=c(2, 1), mar=c(3, 3, 0.2, 0.1), mgp=c(2, 0.6, 0), xpd=FALSE)
spectrum(xx, main="", ylim=c(1e-15, 0.1), sub="")
spectrum(xx.lp, main="", ylim=c(1e-15, 0.1), sub="")

enter image description here

如您所见,没有相移

par(mfrow=c(3, 1), mar=c(3, 3, 0.2, 0.1), mgp=c(2, 0.6, 0), xpd=FALSE)
plot(xx[1:(sf/2)], type="l", ylim=c(-1, 1))
plot(xx.lp[1:(sf/2)], type="l", ylim=c(-1, 1))
plot(xx.o[1:(sf/2)], type="l", ylim=c(-1, 1))

enter image description here