I'd like to forecast (or predict) a time series with weights.
The following works using the regular l
inear m
odelling techniques of lm
by applying a (sigmoidal) weight distribution to the input data, essentially weighing the latter data points more heavily than the former:
library("stats")
lm.weight.function <- function(x) {10 / (1 + exp(-x))} # Sigmoidal
lm.weights <- lapply(seq(-13, 14, length.out = 27), lm.weight.function)
lm.input <- as.data.frame(c(23957, 46771, 60767, 73284, 60296, 73122, 78304, 87154, 80459, 76885, 56479, 18809, 13453, 13951, 25140, 12035, 11920, 20683, 30357, 35019, 37732, 46150, 47856, 41931, 20985, 32526, 27283))
lm.input <- cbind(1:27, lm.input)
colnames(lm.input) <- c('x', 'y')
lm.model <- lm(formula = y ~ log(x), data = lm.input, weights = unlist(lm.weights))
predict.input <- as.data.frame(28:55)
colnames(predict.input) <- 'x'
predict.model <- predict(lm.model, predict.input)
plot(1:(27+28), c(lm.input$y, predict.model), type = 'l', xlab = 'x', ylab = 'y')
Now I wish to do the same using the forecast
package. However, I'm having difficulty specifying the weights
:
library("forecast")
ts.weight.function <- function(x) {10 / (1 + exp(-x))} # Sigmoidal
ts.weights <- as.data.frame(lapply(seq(-13, 14, length.out = 27), ts.weight.function))
colnames(ts.weights) <- 'trend'
ts.input <- ts(c(23957, 46771, 60767, 73284, 60296, 73122, 78304, 87154, 80459, 76885, 56479, 18809, 13453, 13951, 25140, 12035, 11920, 20683, 30357, 35019, 37732, 46150, 47856, 41931, 20985, 32526, 27283), frequency = 1)
ts.model <- tslm(formula = ts.input ~ log(trend), weights = unlist(ts.weights))
The above prints an error:
Error in eval(expr, envir, enclos) :
..1 used in an incorrect context, no ... to look in
How can I use tslm
to forecast a time series with weights?
Best Answer
This is an issue with
lm
.produces the exact same error. If you read the source code to
tslm
, you'll find thatlm
is called in more or less the sam way.I found here that
..1
means the first argument included in...
, which in this case is the only argument,weights
. It suggests that this kind of error could be caused because argument being passed doesn't exist in the environment from which the function is being called. You can see this behavior withwrapper(ts.input~x,weights=foo)
if you don't have any object calledfoo
.Running a traceback on
wrapper(ts.input~x,weights=ts.weights)
reveals:And in the source code of
lm
,which suggests that the call to
model.frame
is picking up on the...
in a strange way.So I decided to try it without
...
:which produced
invalid type (closure) for variable '(weights)'
A closure, of course, is a function in R. Which can mean only one thing...
weights
is already a function in the global environment. Indeed,?weights
reveals that it's ironically the extractor function for model weights. It's a no-brainer that it gets search priority over local variables. So I changed the argument names (sinceformula
is also a function):now produces
And if you run
traceback
you still get the same issue withmodel.frame
. So I'm completely baffled. My only conclusion is that a) it has nothing to do withtslm
or time series analysis, and b) the problem lies somewhere in the way arguments are passed around insidelm
.That probably doesn't help you at all, but hopefully at least someone can come along and explain what's going on here. My provisional answer to your actual question of how to use weights in
tslm
is that you can't.