Skip to content

Commit

Permalink
cleaned up more broom and accuracy issues
Browse files Browse the repository at this point in the history
  • Loading branch information
eeholmes committed May 10, 2023
1 parent ca0e853 commit ef35bf4
Show file tree
Hide file tree
Showing 21 changed files with 74 additions and 97 deletions.
5 changes: 2 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@ Version: 3.11.6
Date: 2023-05-10
Depends: R (>= 3.5.0)
Imports:
graphics, grDevices, KFAS (>= 1.0.1), mvtnorm, nlme, stats, utils
generics (>= 0.1.2), graphics, grDevices, KFAS (>= 1.0.1), mvtnorm, nlme, stats, utils
Suggests:
broom,
forecast,
Formula,
forecast,
ggplot2,
gridExtra,
Hmisc,
Expand Down
51 changes: 22 additions & 29 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@

## export functions
export(
accuracy,
autoplot.marssMLE,
autoplot.marssPredict,
CSEGriskfigure,
CSEGtmufigure,
forecast,
glance,
MARSS,
MARSSaic,
MARSSboot,
Expand All @@ -23,15 +28,9 @@ export(
MARSSsimulate,
MARSSFisherI,
MARSSvectorizeparam,
tidy,
zscore,
ldiag,
autoplot.marssMLE,
autoplot.marssPredict,
accuracy.marssMLE,
accuracy.marssPredict,
forecast.marssMLE,
glance.marssMLE,
tidy.marssMLE
ldiag
)

#these are part of base, but user could unattach them and then MARSS wouldn't work
Expand All @@ -44,12 +43,24 @@ importFrom(mvtnorm, rmvnorm)
importFrom(nlme, fdHess)
importFrom(KFAS, SSModel, SSMcustom, KFS)
importFrom("grDevices", "contourLines")
importFrom(generics,forecast)
importFrom(generics,accuracy)
importFrom(generics,glance)
importFrom(generics,tidy)

## register S3 methods
export(MARSSfit) # method
S3method(MARSSfit, kem)
S3method(MARSSfit, BFGS)

S3method(accuracy, marssMLE)
S3method(accuracy, marssPredict)
S3method(coef, marssMLE)
S3method(fitted, marssMLE)
S3method(forecast, marssMLE)
S3method(glance, marssMLE)
S3method(model.frame, marssMODEL)
S3method(model.frame, marssMLE)
S3method(print, marssMODEL)
S3method(print, marssMLE)
S3method(print, marssPredict)
Expand All @@ -58,37 +69,19 @@ S3method(plot, marssPredict)
S3method(plot, marssResiduals)
S3method(stats::predict, marssMLE)
S3method(logLik, marssMLE)
S3method(fitted, marssMLE)
S3method(summary, marssMODEL)
S3method(summary, marssMLE)
S3method(coef, marssMLE)
S3method(residuals, marssMLE)
S3method(model.frame, marssMODEL)
S3method(model.frame, marssMLE)
S3method(simulate, marssMLE)
S3method(summary, marssMODEL)
S3method(summary, marssMLE)
S3method(tidy, marssMLE)
S3method(toLatex, marssMODEL)
S3method(toLatex, marssMLE)
S3method(stats::tsSmooth, marssMLE)

# Declare these methods if the user has the package
if(getRversion() >= "3.6.0") {
S3method(broom::glance, marssMLE)
S3method(broom::tidy, marssMLE)
S3method(ggplot2::autoplot, marssMLE)
S3method(ggplot2::autoplot, marssPredict)
S3method(ggplot2::autoplot, marssResiduals)
S3method(forecast::accuracy, marssMLE)
S3method(forecast::accuracy, marssPredict)
S3method(forecast::forecast, marssMLE)
}


# Another approach for the broom and ggplot2 S3 methods is
# to put broom and ggplot2 in imports
# importFrom(broom, glance, tidy)
# importFrom(ggplot2, autoplot)
# S3method(augment, marssMLE)
# S3method(glance, marssMLE)
# S3method(tidy, marssMLE)
# S3method(autoplot, marssMLE)

3 changes: 2 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ This release is focused on adding new method `method="TMB"` which uses the packa
* Added the generic function `MARSSfit()` and methods for "kem" and "BFGS".
* Added the defaults to `R/onLoad.R` and made it easier to specify new methods and constraints on methods
* Made changes to `checkMARSSinputs.R`, `is_marssMLE.R` and `is.validvarcov()` so they are not so specific to `method="BFGS"` but work for any methods with similar constraints.
* Export MARSSvectorizeparam. Need when writing methods for MARSSfit() generic.
* Export MARSSvectorizeparam(). Need when writing methods for MARSSfit() generic.
* Added {generics} as a dependency and removed {forecast} and {broom} from Suggests. Cleaned up examples and text throughout to remove references to these packages.

## BUGS

Expand Down
28 changes: 14 additions & 14 deletions R/accuracy_marssMLE.R
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
accuracy.marssPredict <- function(f, x, test = NULL, type = "ytt1", verbose = FALSE, ...) {
out <- accuracy.marssMLE(f$model, test = test, type = type, verbose = verbose)
accuracy.marssPredict <- function(object, x, test = NULL, type = "ytt1", verbose = FALSE, ...) {
out <- accuracy.marssMLE(object$model, test = test, type = type, verbose = verbose)

if (!missing(x)) {
dotest <- TRUE
if (f$h == 0) {
if (object$h == 0) {
message("Test data (x) passed in but object is not a forecast (h=0). Test data ignored.")
dotest <- FALSE
}
if (dotest) { # f is a marssPredict object
if (dotest) { # object is a marssPredict object
# set up the predictions
n <- attr(f$model$model, "model.dims")[["y"]][1]
h <- f$h
n <- attr(object$model$model, "model.dims")[["y"]][1]
h <- object$h

TT <- attr(f$model$model, "model.dims")[["x"]][2]
loc <- which(colnames(f$pred) == "se")
testset <- subset(f$pred, f$t > TT)[, c(".rownames", "y", "estimate")]
TT <- attr(object$model$model, "model.dims")[["x"]][2]
loc <- which(colnames(object$pred) == "se")
testset <- subset(object$pred, object$t > TT)[, c(".rownames", "y", "estimate")]
colnames(testset) <- c(".rownames", "y", ".fitted")
testset$t <- rep(1:h, n)

Expand All @@ -23,13 +23,13 @@ accuracy.marssPredict <- function(f, x, test = NULL, type = "ytt1", verbose = FA
if (!is.matrix(x) && !is.data.frame(x)) {
stop("accuracy.marssMLE: Test data must be a matrix or data frame.\n", call. = FALSE)
}
Y.names <- attr(f$model$model, "Y.names")
Y.names <- attr(object$model$model, "Y.names")
if (is.matrix(x)) {
if (nrow(x) != n) stop(paste0("accuracy.marssPredict: Test data must have the same number of rows (n=", n, ") as training data.\n"), call. = FALSE)
if (ncol(x) != h) stop(paste0("accuracy.marssPredict: Test data must have the same columns as time steps (h=", h, ") as in the forecast.\n"), call. = FALSE)
if (is.null(rownames(x))) {
message("Training data rownames being used as rownames for test data.")
rownames(x) <- attr(f$model$model, "Y.names")
rownames(x) <- attr(object$model$model, "Y.names")
}
val <- Y.names %in% rownames(x)
if (!all(val)) stop(paste0("accuracy.marssPredict: Test data is missing ", paste(Y.names[!val], collapse = " ,"), ".\n"), call. = FALSE)
Expand Down Expand Up @@ -66,15 +66,15 @@ accuracy.marssPredict <- function(f, x, test = NULL, type = "ytt1", verbose = FA
return(out)
}

accuracy.marssMLE <- function(f, x = NULL, test = NULL, type = "ytt1", verbose = FALSE, ...) {
accuracy.marssMLE <- function(object, x = NULL, test = NULL, type = "ytt1", verbose = FALSE, ...) {
if (!missing(x)) {
message("Test data (x) passed in but object is not a forecast. x ignored.")
}
rout <- c("Training set")
fx <- fitted(f, type = type)
fx <- fitted(object, type = type)
out <- aout(fx, test)
rownames(out) <- rout
n <- attr(f$model, "model.dims")[["y"]][1]
n <- attr(object$model, "model.dims")[["y"]][1]
if (!verbose && n != 1) {
return(out)
}
Expand Down
2 changes: 1 addition & 1 deletion R/glance_marssMLE.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
###############################################################################################################################################
# glance method for class marssMLE. For package broom
# glance method for class marssMLE. For package generics
##############################################################################################################################################
glance.marssMLE <- function(x, ...) {
a <- residuals.marssMLE(x, type = "tt1")
Expand Down
1 change: 0 additions & 1 deletion inst/doc/Chapter_StructuralBreaks.R
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ library(Formula)
library(ggplot2)
library(Hmisc)
library(datasets)
library(broom)


###################################################
Expand Down
2 changes: 1 addition & 1 deletion inst/doc/Chapter_Structural_TS.R
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ rbind(
### code chunk number 20: Cs405_forecast
###################################################
fr1 <- forecast:::forecast.StructTS(fit1, h = 10)
fr2 <- forecast.marssMLE(fit2, h = 10)
fr2 <- forecast(fit2, h = 10)
p1 <- ggplot2::autoplot(fr1, include = 8)
p2 <- ggplot2::autoplot(fr2, include = 8)
gridExtra::grid.arrange(p1, p2, nrow = 1)
Expand Down
4 changes: 2 additions & 2 deletions inst/doc/Quick_Examples.R
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,8 @@ x <- print(kem, what = "states", silent = TRUE)
###################################################
### code chunk number 27: Cs24_model-tidy-R
###################################################
broom::tidy(kem)
broom::glance(kem)
tidy(kem)
glance(kem)


###################################################
Expand Down
14 changes: 7 additions & 7 deletions man/accuracy_marssMLE.Rd
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
\name{accuracy.marssMLE}
\alias{accuracy.marssMLE}
\name{accuracy}
\alias{accuracy}
\alias{accuracy.marssPredict}
\alias{accuracy.marssMLE}

\title{Return accuracy metrics}
\usage{
accuracy.marssPredict(f, x, test = NULL, type = "ytt1", verbose = FALSE, ...)
accuracy.marssMLE(f, x, test = NULL, type = "ytt1", verbose = FALSE, ...)
\method{accuracy}{marssPredict}(object, x, test = NULL, type = "ytt1", verbose = FALSE, ...)
\method{accuracy}{marssMLE}(object, x, test = NULL, type = "ytt1", verbose = FALSE, ...)
}
\arguments{
\item{f}{A \code{\link{marssMLE}} or \code{\link{marssPredict}} object}
\item{object}{A \code{\link{marssMLE}} or \code{\link{marssPredict}} object}
\item{x}{A matrix or data frame with data to test against the h steps of a forecast.}
\item{test}{Which time steps in training data (data model fit to) to compute accuracy for.}
\item{type}{type="ytt1" is the one-step-ahead predictions. type="ytT" is the fitted ytT predictions. The former are standardly used for training data prediction metrics.}
\item{verbose}{Show metrics for each time series of data.}
\item{...}{Not used.}
}
\description{
This is a method for the generic \code{accuracy} function in the forecast package. The forecast package is not part of the MARSS package and you will need to load it separately (See examples). Alternatively you can use \code{accuracy.marssMLE()} or \code{accuracy.marssPredict()}.
This is a method for the generic \code{accuracy} function in the generics package. It is written to mimic the output from the accuracy function in the forecast package. See that package for details.

The measures calculated are:
\itemize{
Expand All @@ -39,7 +40,6 @@ dat <- dat[c(2, 11, 12),]
train.dat <- dat[,1:12]
fit <- MARSS(train.dat, model = list(Z = factor(c("WA", "OR", "OR"))))

library(forecast)
accuracy(fit)

# Compare to test data set
Expand Down
2 changes: 1 addition & 1 deletion man/coef_marssMLE.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

\title{ Coefficient function for MARSS MLE objects }
\description{
\code{\link{MARSS}()} outputs \code{\link{marssMLE}} objects. \code{coef(object)}, where \code{object} is the output from a \code{\link{MARSS}()} call, will print out the estimated parameters. The default output is a list with values for each parameter, however the output can be altered using the \code{type} argument to output a vector of all the estimated values (\code{type="vector"}) or a list with the full parameter matrix with the estimated and fixed elements (\code{type="matrix"}). Note, if you just want a summary of the parameter estimates, try \code{\link{tidy.marssMLE}(object)} (or \code{tidy(object)} if you have the broom package loaded).
\code{\link{MARSS}()} outputs \code{\link{marssMLE}} objects. \code{coef(object)}, where \code{object} is the output from a \code{\link{MARSS}()} call, will print out the estimated parameters. The default output is a list with values for each parameter, however the output can be altered using the \code{type} argument to output a vector of all the estimated values (\code{type="vector"}) or a list with the full parameter matrix with the estimated and fixed elements (\code{type="matrix"}). For a summary of the parameter estimates with CIs from the estimated Hessian, use try \code{tidy(object)}.
}
\usage{
\method{coef}{marssMLE}(object, ..., type = "list", form = NULL, what = "par")
Expand Down
10 changes: 3 additions & 7 deletions man/forecast_marssMLE.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
\description{
\code{\link{MARSS}()} outputs \code{\link{marssMLE}} objects. \code{forecast(object)}, where object is \code{\link{marssMLE}} object, will return the forecasts of \eqn{\mathbf{y}_t}{y(t)} or \eqn{\mathbf{x}_t}{x(t)} for \code{h} steps past the end of the model data. \code{forecast(object)} returns a \code{\link{marssPredict}} object which can be passed to \code{\link{plot.marssPredict}} for automatic plotting of the forecast. \code{forecast.marssMLE()} is used by \code{\link{predict.marssMLE}()} to generate forecasts.

This is a method for the generic \code{forecast} function in the forecast package. The forecast package is not part of the MARSS package and you will need to load it separately. Alternatively you can use \code{forecast.marssMLE()} instead of \code{forecast()}.
This is a method for the generic \code{forecast} function in the generics package. It is written to mimic the behavior and look of the forecast package.
}
\usage{
\method{forecast}{marssMLE}(object, h = 10, level = c(0.8, 0.95),
Expand Down Expand Up @@ -70,15 +70,11 @@ dat <- dat[2:4,] #remove the year row
fit <- MARSS(dat, model=list(R="diagonal and equal"))

# 2 steps ahead forecast
fr <- forecast.marssMLE(fit, type="ytT", h=2)
fr <- forecast(fit, type="ytT", h=2)
plot(fr)

# forecast and only show last 10 steps of original data
fr <- forecast.marssMLE(fit, h=10)
fr <- forecast(fit, h=10)
plot(fr, include=10)

# if you load the forecast package, you can use
library(forecast)
fr <- forecast(fit)

}
6 changes: 3 additions & 3 deletions man/glance_marssMLE.Rd
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
\name{glance.marssMLE}
\name{glance}
\alias{glance}
\alias{glance.marssMLE}

\title{Return brief summary information on a MARSS fit}
\usage{
glance.marssMLE(x, ...)
\method{glance}{marssMLE}(x, ...)
}
\arguments{
\item{x}{A \code{\link{marssMLE}} object}
Expand All @@ -30,6 +31,5 @@ dat <- t(harborSeal)
dat <- dat[c(2, 11, 12), ]
fit <- MARSS(dat, model = list(Z = factor(c("WA", "OR", "OR"))))

library(broom)
glance(fit)
}
5 changes: 1 addition & 4 deletions man/plot_marssPredict.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ fr <- predict(fit, n.ahead=10)
plot(fr, include=10)
# forecast.marssMLE does the same thing as predict with h
fr <- forecast.marssMLE(fit, n.ahead=10)
fr <- forecast(fit, n.ahead=10)
plot(fr)
# without h, predict will show the prediction intervals
Expand All @@ -74,8 +74,5 @@ fr <- predict(fit, newdata=list(y=dat[3:4,]), x0="reestimate")
plot(fr)
# forecast; note h not n.ahead is used for forecast()
fr <- forecast.marssMLE(fit, h=10)
# If you load the forecast package, this will work
library(forecast)
fr <- forecast(fit, h=10)
}
12 changes: 3 additions & 9 deletions man/tidy_marssMLE.Rd
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
\name{tidy.marssMLE}
\alias{tidy}
\alias{tidy.marssMLE}
\title{Return estimated parameters with summary information}
\description{

\code{tidy.marssMLE} returns the parameter estimates and their confidence intervals.

The tidy function is designed to work with the \code{broom} package and you will need to load that package if you want to call \code{tidy(fit)} instead of \code{tidy.marssMLE(fit)}.
\code{tidy.marssMLE} is the method for the tidy generic. It returns the parameter estimates and their confidence intervals.
}
\usage{
tidy.marssMLE(x, conf.int = TRUE, conf.level = 0.95, ...)
\method{tidy}{marssMLE}(x, conf.int = TRUE, conf.level = 0.95, ...)
}
\arguments{
\item{x}{a \code{\link{marssMLE}} object}
Expand Down Expand Up @@ -37,11 +36,6 @@ dat <- dat[c(2, 11, 12), ]
fit <- MARSS(dat)

# A data frame of the estimated parameters
tidy.marssMLE(fit)

# If broom is used

library(broom)
tidy(fit)

}
6 changes: 3 additions & 3 deletions tests/testthat/test-forecast.R
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ fits[[7]] <- MARSS(i$data, model = i$model, control = i$control, silent = TRUE,

for(i in c(3,6)){
fit <- fits[[i]]
p1 <- try(forecast.marssMLE(fit, h=10), silent=TRUE)
p1 <- try(forecast(fit, h=10), silent=TRUE)
test_that(paste("forecast class", i), {
expect_true(inherits(p1, "try-error"))
})
Expand All @@ -31,7 +31,7 @@ for(i in c(3,6)){

for(i in c(1:2,4,5,7)){
fit <- fits[[i]]
p1 <- try(forecast.marssMLE(fit, h=10), silent=TRUE)
p1 <- try(forecast(fit, h=10), silent=TRUE)
test_that(paste("forecast class", i), {
expect_true(inherits(p1, "marssPredict"))
})
Expand All @@ -55,7 +55,7 @@ for (Q in list("unconstrained", "diagonal and equal", "equalvarcov", "zero")) {
if (Q == "zero" && R == "zero") next
if (Q == "zero" && B != "identity") next
fit <- MARSS(dat, model = mod, silent = TRUE)
p1 <- try(forecast.marssMLE(fit, h=10), silent=TRUE)
p1 <- try(forecast(fit, h=10), silent=TRUE)
test_that(paste("forecast class", Q, R, B), {
expect_true(inherits(p1, "marssPredict"))
})
Expand Down
Loading

0 comments on commit ef35bf4

Please sign in to comment.