# File src/library/stats/R/filter.R # Part of the R package, https://www.R-project.org # # Copyright (C) 1999-2017 The R Core Team # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # A copy of the GNU General Public License is available at # https://www.R-project.org/Licenses/ filter <- function(x, filter, method = c("convolution", "recursive"), sides = 2L, circular = FALSE, init=NULL) { method <- match.arg(method) x <- as.ts(x) storage.mode(x) <- "double" xtsp <- tsp(x) n <- as.integer(NROW(x)) if (is.na(n)) stop(gettextf("invalid value of %s", "NROW(x)"), domain = NA) nser <- NCOL(x) filter <- as.double(filter) nfilt <- as.integer(length(filter)) if (is.na(nfilt)) stop(gettextf("invalid value of %s", "length(filter)"), domain = NA) if(anyNA(filter)) stop("missing values in 'filter'") if(method == "convolution") { if(nfilt > n) stop("'filter' is longer than time series") sides <- as.integer(sides) if(is.na(sides) || (sides != 1L && sides != 2L)) stop("argument 'sides' must be 1 or 2") circular <- as.logical(circular) if (is.na(circular)) stop("'circular' must be logical and not NA") if (is.matrix(x)) { y <- matrix(NA, n, nser) for (i in seq_len(nser)) y[, i] <- .Call(C_cfilter, x[, i], filter, sides, circular) } else y <- .Call(C_cfilter, x, filter, sides, circular) } else { if(missing(init)) { init <- matrix(0, nfilt, nser) } else { ni <- NROW(init) if(ni != nfilt) stop("length of 'init' must equal length of 'filter'") if(NCOL(init) != 1L && NCOL(init) != nser) { stop(sprintf(ngettext(nser, "'init' must have %d column", "'init' must have 1 or %d columns", domain = "R-stats"), nser), domain = NA) } if(!is.matrix(init)) dim(init) <- c(nfilt, nser) } ind <- seq_len(nfilt) ## NB: this .Call alters its third argument if (is.matrix(x)) { y <- matrix(NA, n, nser) for (i in seq_len(nser)) y[, i] <- .Call(C_rfilter, x[, i], filter, c(rev(init[, i]), double(n)))[-ind] } else y <- .Call(C_rfilter, x, filter, c(rev(init[, 1L]), double(n)))[-ind] } # y <- drop(y) tsp(y) <- xtsp class(y) <- if(nser > 1L) c("mts", "ts") else "ts" y }