我以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低通滤波器吗?任何帮助将不胜感激。
答案 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="")
如您所见,没有相移
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))