我正在尝试使用Chebyshev过滤器来平滑时间序列,但不幸的是,数据系列中有NA。
例如,
t <- seq(0, 1, len = 100)
x <- c(sin(2*pi*t*2.3) + 0.25*rnorm(length(t)),NA, cos(2*pi*t*2.3) + 0.25*rnorm(length(t)))
我正在使用Chebyshev过滤器:cf1 = cheby1(5, 3, 1/44, type = "low")
我正在尝试过滤排除NAs的时间序列,但不会搞砸订单/位置。所以,我已经尝试了na.rm=T
,但似乎没有这样的论点。
然后
z <- filter(cf1, x) # apply filter
谢谢你们。
答案 0 :(得分:2)
尝试使用x <- x[!is.na(x)]
删除NA,然后运行过滤器。
答案 1 :(得分:1)
您可以使用compelete.cases
功能预先删除NA。您也可以考虑输入缺失的数据。查看mtsdi或Amelia II软件包。
修改强>
这是Rcpp的解决方案。这可能有用,速度很重要:
require(inline)
require(Rcpp)
t <- seq(0, 1, len = 100)
set.seed(7337)
x <- c(sin(2*pi*t*2.3) + 0.25*rnorm(length(t)),NA, cos(2*pi*t*2.3) + 0.25*rnorm(length(t)))
NAs <- x
x2 <- x[!is.na(x)]
#do something to x2
src <- '
Rcpp::NumericVector vecX(vx);
Rcpp::NumericVector vecNA(vNA);
int j = 0; //counter for vx
for (int i=0;i<vecNA.size();i++) {
if (!(R_IsNA(vecNA[i]))) {
//replace and update j
vecNA[i] = vecX[j];
j++;
}
}
return Rcpp::wrap(vecNA);
'
fun <- cxxfunction(signature(vx="numeric",
vNA="numeric"),
src,plugin="Rcpp")
if (identical(x,fun(x2,NAs)))
print("worked")
# [1] "worked"
答案 2 :(得分:1)
我不知道ts
对象是否可以包含缺失值,但如果您只想重新插入NA
值,则可以使用?insert
中的R.utils
}。可能有更好的方法来做到这一点。
install.packages(c('R.utils', 'signal'))
require(R.utils)
require(signal)
t <- seq(0, 1, len = 100)
set.seed(7337)
x <- c(sin(2*pi*t*2.3) + 0.25*rnorm(length(t)), NA, NA, cos(2*pi*t*2.3) + 0.25*rnorm(length(t)), NA)
cf1 = cheby1(5, 3, 1/44, type = "low")
xex <- na.omit(x)
z <- filter(cf1, xex) # apply
z <- as.numeric(z)
for (m in attributes(xex)$na.action) {
z <- insert(z, ats = m, values = NA)
}
all.equal(is.na(z), is.na(x))
?insert
答案 3 :(得分:0)
这是一个可用于过滤带有NA的信号的函数。 NAs被忽略而不是被零替换。
然后,您可以指定NA在过滤后的信号的任何点可以采取的最大权重百分比。如果特定点的NA(实际数据太少)过多,则过滤后的信号本身将设置为NA。
# This function applies a filter to a time series with potentially missing data
filter_with_NA <- function(x,
window_length=12, # will be applied centrally
myfilter=rep(1/window_length,window_length), # a boxcar filter by default
max_percentage_NA=25) # which percentage of weight created by NA should not be exceeded
{
# make the signal longer at both sides
signal <- c(rep(NA,window_length),x,rep(NA,window_length))
# see where data are present and not NA
present <- is.finite(signal)
# replace the NA values by zero
signal[!is.finite(signal)] <- 0
# apply the filter
filtered_signal <- as.numeric(filter(signal,myfilter, sides=2))
# find out which percentage of the filtered signal was created by non-NA values
# this is easy because the filter is linear
original_weight <- as.numeric(filter(present,myfilter, sides=2))
# where this is lower than one, the signal is now artificially smaller
# because we added zeros - compensate that
filtered_signal <- filtered_signal / original_weight
# but where there are too few values present, discard the signal
filtered_signal[100*(1-original_weight) > max_percentage_NA] <- NA
# cut away the padding to left and right which we previously inserted
filtered_signal <- filtered_signal[((window_length+1):(window_length+length(x)))]
return(filtered_signal)
}