Closed YalanHu closed 5 years ago
I can't reproduce the problem. The following code works, for example.
library(forecast)
y <- rnorm(30)
x <- rnorm(30)
model <- Arima(y, order=c(1,0,0), xreg=x)
xreg.test <- 0
forecast(model, xreg=xreg.test)
#> Point Forecast Lo 80 Hi 80 Lo 95 Hi 95
#> 31 -0.07488821 -1.25107 1.101294 -1.873704 1.723927
xreg.test <- matrix(xreg.test, ncol=1)
forecast(model, xreg=xreg.test)
#> Point Forecast Lo 80 Hi 80 Lo 95 Hi 95
#> 31 -0.07488821 -1.25107 1.101294 -1.873704 1.723927
Created on 2019-08-03 by the reprex package (v0.3.0)
Please provide a reproducible example.
# my example use a dataset from TSstudio
library(TSstudio)
library(forecast)
# Load the series
data("USgas")
# Get the series info
ts_info(USgas)
x_reg <- forecast::fourier(USgas, K = 5)
ts.obj <- USgas
ts.subset <- split_ts <- train <- test <- NULL
i <- 200
window_size <- 1
ts.subset <- stats::window(ts.obj, start = stats::time(ts.obj)[1], end = stats::time(ts.obj)[i])
split_ts <- TSstudio::ts_split(ts.subset, sample.out = window_size)
train <- split_ts$train
test <- split_ts$test
a.xreg.train <- x_reg[1:length(train),]
a.xreg.test <- x_reg[(length(train) + 1):(length(train) + window_size),]
a.arg <- NULL
a.arg.xreg <- a.arg
a.arg.xreg$xreg <- a.xreg.train
md <- base::do.call(forecast::auto.arima, c(list(train), a.arg.xreg))
fc <- forecast::forecast(md, h = window_size, xreg = a.xreg.test)
fc <- forecast::forecast(md, h = window_size, xreg = t(a.xreg.test))
This is not a bug. xreg
must either be a numerical vector (if you have one covariate) or a matrix (if you have multiple covariates). Since you have multiple covariates, you need to pass it as matrix. Your t()
function is doing that.
I understood, however, if you use as.matrix and not transpose then this will not work. so the problem is not about matrix. It due to the slicing behavior of R, slice only one Row of a matrix, its columns will become rows.
I agree it is not a bug, but to make it more transparent to user, is it possible to check the dimension inside the code? for example the window_size not equal to 1, it will not have problem. so from 1 to n shouldn't have sudden change.
It will work with matrix(xreg, nrow=1)
. Or if you are extracting one row from a matrix, you can use xreg[1,, drop=FALSE]
Converting to a matrix when the length of the vector is the same as the number of expected columns seems a little dangerous. The user may have accidentally passed only the first column, and there is no way to know if they meant to provide the data as a row instead.
is it possible to use the colnames/names to match instead only based on the number of columns?
Yes, it would be possible, but not something I want to do.
Closing as there is a solution to the problem. For better handling of exogenous regressors I recommend looking into the fable package.
in the arima.R line # 350 if (NCOL(xreg) != NCOL(object$call$xreg)) { stop("Number of regressors does not match fitted model") }
the above will not work when h=1 , as the xreg.test will become an array, and the NCOL will return 1 instead the number of columns as the train xreg.
fc <- forecast::forecast(model, h = 1, xreg = xreg.test) doesn't work
fc <- forecast::forecast(model, h = 1, xreg = t(xreg.test)) works