rlatexvarmodelsummarymultivariate-time-series

How can I report a VARX model (MTS class) with modelsummary (or other LaTeX table packages) in R?


Consider an example of a VARX model estimate in R, using MTS package:

library(tidyverse)
library(MTS)
library(modelsummary)
library(vars)
library(stats)

set.seed(10)

ts1 <- rnorm(200, mean = 10, sd = 3) %>% ts()
ts2 <- ts1 + rnorm(200, mean = 1, sd = 3) %>% ts()

exg1 <- rchisq(n = 200,df = 10) + ts1 %>% ts()
exg2 <- rf(n = 200,df1 = 20,df2 = 20) + ts2 %>% ts()

zt <- cbind(ts1, ts2)
xt <- cbind(exg1, exg2)
p = 1
m = 0

varx <- VARX(zt = zt, p = p, xt = xt, m = m)

I would like to report this model as a LaTeX table, such as the output table of a lm() model:

\begin{table}
\centering
\begin{tabular}[t]{lc}
\toprule
  & ts1\\
\midrule
(Intercept) & \num{1.676}\\
 & (\num{0.640})\\
ts2\_lag & \num{0.133}\\
 & \vphantom{1} (\num{0.223})\\
exg1 & \num{0.165}\\
 & (\num{0.028})\\
exg2 & \num{0.273}\\
 & (\num{0.223})\\
\midrule
Num.Obs. & \num{200}\\
R2 & \num{0.561}\\
R2 Adj. & \num{0.554}\\
AIC & \num{832.4}\\
BIC & \num{848.9}\\
Log.Lik. & \num{-411.211}\\
F & \num{83.346}\\
RMSE & \num{1.89}\\
\bottomrule
\end{tabular}
\end{table}

According to modelsummary, I can report this model if I create a tidy.mts function that returns a dataframe with a column called term and a glance.mts function with goodness of fit statistics. But the following code doesn't produce a modelsummary table:


tidy.mts <- function(s, ...) {
  
  colnames(s$se.coef) <- colnames(s$coef)
  
  ret <- data.frame(
    term= rownames(s$coef),
    estimate= round(s$coef,3),
    std.error= round(s$se.coef,3))
  
  ret
}

glance.mts <- function(s, ...) {
  
  ret <- data.frame(
    n = nrow(s$data)
  )
  ret
}

modelsummary(varx)

The error message is:

Error: `modelsummary could not extract the required information from a model of
  class "mts". The package tried a sequence of 2 helper functions to extract
  estimates:
  
  parameters::parameters(model)
  broom::tidy(model)
  
  To draw a table, one of these commands must return a `data.frame` with a
  column named "term". The `modelsummary` website explains how to summarize
  unsupported models or add support for new models yourself:
  https://vincentarelbundock.github.io/modelsummary/articles/modelsummary.html
  
  These errors messages were generated during extraction:
  
  `parameters::parameters(model)` did not return a valid data.frame.
`broom::tidy(model)` did not return a valid data.frame.
In addition: Warning message:
`modelsummary could not extract goodness-of-fit statistics from a model
of class "mts". The package tried a sequence of 2 helper functions:

performance::model_performance(model)
broom::glance(model)

One of these functions must return a one-row `data.frame`. The `modelsummary` website explains how to summarize unsupported models or add support for new models yourself:

https://vincentarelbundock.github.io/modelsummary/articles/modelsummary.html 

Solution

  • There are many problems in your solution.

    1. The varx object is of class list, not of class mts, which is what your tidy and glance methods look for. You can manually assign your model a class: class(varx)<-"mts"
    2. The estimate and std.error columns in tidy() should not be rounded. They should be numeric values.
    3. estimate and std.error columns in tidy() should be a single column. However, when you call s$coef, you get two columns. Make sure calling tidy(varx) produces the same kind of data frame as when you call the same function on a lm() model.
    4. The number of observations should be called nobs. This will ensure that it is nicely renamed in the table.