The MARSS_tmb()
function allows you to fit DFAs with the
same form as MARSS(x, form="dfa")
. This has a diagonal
\(\mathbf{Q}\) with 1 on the diagonal
and a stochastic \(\mathbf{x}_1\) with
mean 0 and variance of 5 (diagonal variance-covariance matrix). There
are only 3 options allowed for \(\mathbf{R}\): diagonal and equal, diagonal
and unequal, and unconstrained.
library(MARSS)
data(lakeWAplankton, package = "MARSS")
<- c("Cryptomonas", "Diatoms", "Greens", "Unicells", "Other.algae")
phytoplankton <- as.data.frame(lakeWAplanktonTrans) |>
dat subset(Year >= 1980 & Year <= 1989) |>
subset(select=phytoplankton) |>
t() |>
::zscore() MARSS
<- list(R='unconstrained', m=1, tinitx=1) mod.list
Fit with MARSS with EM or optim and BFGS.
<- MARSS(dat, model=mod.list, form='dfa', z.score=FALSE, silent = TRUE)
m1 <- MARSS(dat, model=mod.list, form='dfa', z.score=FALSE, silent = TRUE, method="BFGS") m2
Fit with TMB.
library(marssTMB)
<- dfaTMB(dat, model=list(m=1, R='unconstrained'))
m3 <- MARSS_tmb(dat, model=mod.list)
m4 <- MARSS_tmb(dat, model=mod.list, control=list(fun.opt="optim")) m5
name | logLik |
---|---|
MARSS-EM | -772.4017 |
MARSS-BFGS | -772.4011 |
dfaTMB-nlminb | -772.4011 |
MARSS_tmb-nlminb | -772.3091 |
MARSS_tmb-optim-BFGS | -875.1003 |
For form="dfa"
, pass in covariates with
covariates=xyz
. If using the default model form (not dfa),
then pass in covariates with model$d
or
model$c
.
# use a simpler R
<- list(m=1, R='diagonal and unequal', tinitx=1)
mod.list2 # add a temperature covariate
<- as.data.frame(lakeWAplanktonTrans) |>
temp subset(Year >= 1980 & Year <= 1989) |>
subset(select=Temp)
<- t(temp) |> zscore()
covar <- system.time(m6 <- MARSS_tmb(dat, model=mod.list2, form="dfa", covariates=covar, silent = TRUE, z.score = FALSE))
t6 <- system.time(m7 <- MARSS(dat, model=mod.list2, form="dfa", covariates=covar, silent = TRUE, control=list(maxit=10000), z.score = FALSE)) t7
Add a 2nd covariate
<- as.data.frame(lakeWAplanktonTrans) |>
TP subset(Year >= 1980 & Year <= 1989) |>
subset(select=TP)
<- rbind(covar, t(TP)) |> zscore()
covar <- system.time(m8 <- MARSS_tmb(dat, model=mod.list2, form="dfa", covariates=covar, silent = TRUE, z.score=FALSE))
t8 <- system.time(m9 <- MARSS(dat, model=mod.list2, form="dfa", covariates=covar, silent = TRUE, control=list(maxit=10000), z.score=FALSE)) t9
name | num_covar | time | logLik |
---|---|---|---|
MARSS-EM | 1 | 0.426 | -752.5472 |
MARSS_tmb-nlminb | 1 | 0.339 | -752.3948 |
MARSS-EM | 2 | 0.478 | -745.5611 |
MARSS_tmb-nlminb | 2 | 0.397 | -745.3983 |
MARSS EM would need to be forced to run for more iterations to reach the same maximum likelihood.
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
<- df |> mutate(mod = paste0(fun, "-", opt.function)) |>
df2 mutate(ncovar = as.factor(ncovar)) |>
group_by(ncovar)
ggplot(df2, aes(alpha=ncovar, fill=mod, y=time, x=m)) +
geom_bar(stat="identity", position="dodge", color="black") +
facet_wrap(~R, scales = "free_y") +
scale_y_continuous() +
ggtitle("TMB is faster than MARSS EM")
#> Warning: Using alpha for a discrete variable is not advised.
<- df |> mutate(mod = paste0(fun, "-", opt.function))
df2 $ncovar <- as.factor(df2$ncovar)
df2ggplot(df2, aes(col=ncovar, y=logLik, x=m, shape=mod)) +
geom_point(position=position_dodge(width=0.3)) +
facet_wrap(~R, scales = "free_y") +
scale_y_continuous() +
ggtitle("logLik comparison")