Skip to content

Migrating from R

Part of The tsecon Guide to Time Series Econometrics. An adoption guide for R users: it maps the packages you already load — vars, svars, lpirfs, BVAR, urca, forecast, tsDyn, rugarch, midasr, plm, quantreg, strucchange, and friends — to tsecon functions, and says plainly where tsecon has no equivalent yet. Every Python block runs against the current library.

R's time-series econometrics is spread across dozens of specialized packages, each with its own conventions, and much of it is unmaintained. tsecon's pitch to an R user is consolidation: one installed library, one calling grammar, one HAC implementation shared across every estimator, and a compiled core that turns the overnight Monte Carlo into a coffee-break one. This page is the translation layer.

What changes when you cross over

Four habits to reset:

  1. No formulas, no data.frame, no model objects. R leans on the formula interface (y ~ x1 + x2) and returns rich S3/S4 objects you inspect with summary(), coef(), irf(). tsecon takes NumPy arrays and returns plain dicts and arrays. You index fit["params"], there is no summary() method, and column order in a matrix carries the meaning R attaches to variable names.

  2. Matrices are T x k (time down the rows). A VAR, a cointegration test, a connectedness table — all take a T x k array with observations in rows and variables in columns, matching how vars and urca expect their input. Panel estimators instead take a list of per-unit arrays (see below), which maps cleanly onto R's split-by-id idiom.

  3. se_type= replaces the vcov zoo. Instead of sandwich::vcovHC, NeweyWest, vcovSCC, and per-package robust options, every regression estimator takes a uniform se_type= argument ("nonrobust", "hc0""hc3", "hac"; panels add "cluster" and "driscoll_kraay"). One implementation, stamped into the result.

  4. Reproducible RNG lives in the arguments. Where R uses a global set.seed(), tsecon's stochastic routines take an explicit seed= and run a parallel Philox stream, so results are bit-reproducible at any thread count.

The mapping tables

"Roadmap" marks a capability tsecon does not ship today. Everything else is callable now.

VARs and structural analysis — vars, svars

R tsecon Notes
vars::VAR(data, p, type="const") var_fit(data, lags=p, trend="c") data is T x k. type="none"/"trend"trend="n"/"t".
vars::irf(v, n.ahead=h, ortho=TRUE) var_irf(data, lags, horizon=h, orth=True) Nested list [h][response][shock].
vars::irf(..., cumulative=TRUE) var_irf(..., cumulative=True) Running sums.
vars::fevd(v, n.ahead=h) var_fevd(data, lags, horizon=h) [horizon][variable][shock], horizon-first like the IRFs; sums to 1 across shocks. R's vars::fevd returns one per-variable matrix — variable-major, one transpose apart.
vars::causality(v, cause=) var_granger(data, caused, causing, lags) F-test. Pass integer column indices.
predict(v, n.ahead=h) var_forecast(data, lags, steps=h, alpha=0.05) {"point", "lower", "upper"}.
svars::id.chol(v) var_irf(..., orth=True) Recursive/Cholesky = column order of data.
VARsignR, svars sign restrictions sign_restricted_svar(data, restrictions, ...) Sign-restricted Bayesian SVAR + identified-set bands.
svars::id.cv (changes in volatility) hetero_svar(data, regime_labels, lags, horizon) Identification through heteroskedasticity (Rigobon 2003; Lanne-Lutkepohl 2008), exactly two known variance regimes; point-identified iff the variance ratios are pairwise distinct.
svars::id.ngml, id.dc (non-Gaussianity / independence) nongaussian_svar(data, lags, horizon) Statistical identification from the residuals alone — deterministic FastICA fixed point, no restriction of any kind. shock_kurtosis flags a near-Gaussian (weakly identified) column. tsecon's route is FastICA, not id.dc's distance covariances; svars' variance-model routes (id.garch, id.st) are roadmap.
vars::BQ (long-run / Blanchard-Quah) long_run_svar(data, lags, horizon, restrictions=None) Closed-form recursive frequency-zero restriction. Returns impact, long_run, irf, cumulative_irf, fevd, long_run_multiplier; point estimates, no RNG.
vars::SVAR(Amat, Bmat) (short-run A/B) Explicit A/B matrices: roadmap. zero_sign_svar gives set identification from zero and sign restrictions; narrative_svar, proxy_svar, max_share_svar and fry_pagan_svar cover the rest of the identification menu.

Local projections — lpirfs

lpirfs is the standard R local-projection package; tsecon covers its main entry points.

R tsecon Notes
lpirfs::lp_lin(..., shock_type) lp(y, shock, horizons, se="lag_augmented") Lag-augmented inference by default (Montiel Olea–Plagborg-Møller 2021).
lpirfs::lp_lin_iv(...) lp_iv(y, impulse, instrument, horizons) Reports a first-stage F.
lpirfs::lp_nl(...) (state-dependent) lp_state(y, shock, state_indicator, ...) Ramey-Zubairy (2018) per-regime IRFs.
lpirfs::lp_lin_panel(...) panel_lp(outcome, shock, ...) Panel LP with fixed effects; Driscoll-Kraay SEs.
Smooth/penalized LP — no lpirfs support smooth_lp(y, shock, horizons, lam="cv") Barnichon-Brownlees (2019) penalized-B-spline IRF, estimated jointly across horizons; cross-validates lam. tsecon-native.

Bayesian VARs — BVAR, bvartools

R tsecon Notes
BVAR::bvar(data, lags, priors=) bvar_fit(data, lags, lambda0, lambda1, lambda3, delta) Minnesota-NIW conjugate posterior + log marginal likelihood.
irf(bv, horizon=h) posterior draws bvar_irf_draws(data, lags, horizon, n_draws, seed) 4-D list [draw][h][variable][shock]; take quantiles for bands.
coda/rstan R-hat, ESS mcmc_diagnostics(chains) Rank-normalized split R-hat and bulk/tail ESS (ArviZ-exact).
Hierarchical / hyperparameter priors bvar_hierarchical(data, lags, optimize="lambda1", hyperprior="glp") Empirical-Bayes / ML-II: picks the Minnesota tightness by maximizing the closed-form marginal likelihood (Giannone-Lenza-Primiceri 2015), then refits the conjugate posterior at the optimum. hyperprior="none" is pure ML-II; the GLP hyperprior is the default because pure ML-II collapsed lambda1 on a fifth of prior draws in audit round 6.
SSVS / spike-and-slab variable selection bvar_ssvs(data, lags, n_draws=, burn=, seed=) George-Sun-Ni (2008) stochastic search, 4-block Gibbs, semi-automatic prior scales from the OLS standard errors; returns inclusion_prob and irf_draws. Stochastic-volatility priors: roadmap.

Cointegration and unit roots — urca, tseries

R tsecon Notes
urca::ur.df(y, type="drift") adf(y, regression="c") Or tseries::adf.test. Dict return with MacKinnon p-value.
urca::ur.kpss(y) kpss(y, regression="c") Null is stationarity.
urca::ur.pp(y), tseries::pp.test phillips_perron(y, regression="c", test_type="tau") Semiparametric unit-root test; test_type="rho" is Z-alpha. Matches arch.unitroot.PhillipsPerron to 1e-10.
urca::ur.ers(y, type="DF-GLS") dfgls(y, regression="c", method="aic") Elliott-Rothenberg-Stock GLS-detrended ADF — the near-optimal-power default over plain adf.
(no CRAN implementation) ng_perron(y, trend="c") Ng-Perron (2001) MZa/MZt/MSB/MPT on the same GLS-detrending engine, MAIC lag selection. Statistic-only: no response surface exists, so none is fabricated — compare against the transcribed Table 1 critical values in crit.
urca::ur.za(y, model="intercept") zivot_andrews(y, regression="c", trim=0.15) One endogenous break; break_index is the last pre-break observation. Matches statsmodels.
urca::ca.jo(data, type="trace", K=) johansen(data, k_ar_diff=K-1) Trace + max-eig stats and selected ranks.
urca::cajorls, vars::vec2var vecm(data, k_ar_diff, coint_rank, deterministic, seasons) ML VECM: alpha, beta, det_coef_coint, gamma, det_coef, sigma_u, llf. deterministic covers all nine statsmodels cases — "n" (default), "co" (unrestricted constant — the case johansen/ca.jo's constant convention assumes), the restricted "ci"/"li" (≈ ca.jo ecdet="const"/"trend", whose coefficients come back as det_coef_coint), "lo", and the combinations — plus centered seasonal dummies (seasons=, ≈ ca.jo(season=)).
tseries::Box.test(y, type="Ljung-Box") ljung_box(y, nlags) Box-Pierce also returned.
tseries::jarque.bera.test(y) jarque_bera(y)
FinTS::ArchTest(y) arch_lm(y, nlags) Engle's ARCH-LM.
ur.df + ur.kpss read together check_stationarity(y) The ADF+KPSS confirmatory-quadrant workflow with a differencing recommendation.
(a whole battery of ur.df/Box.test/ArchTest/Fstats by hand) check_series(y) One-call diagnostic battery returning ordered model recommendations (also runs Johansen + VAR lag search on 2-D input). A tsecon convenience, not a 1:1 port.
urca::ca.po (Phillips-Ouliaris) phillips_ouliaris(y, x, trend="c", test_type="Zt") Residual cointegration test, null is no cointegration. x is the T x m stochastic-regressor block — do not add a constant column, trend supplies the deterministics. test_type="Za" is statistic-only.
tseries::po.test / residual-ADF two-step engle_granger(data, trend="c", autolag="aic") Engle-Granger: column 0 of data is the regressand, columns 1.. its regressors. Statistic and p-value match statsmodels.tsa.stattools.coint (1e-10 / 1e-9); also returns the step-1 coefficients and residuals.

Structural breaks and specification tests — strucchange, lmtest

R tsecon Notes
strucchange::breakpoints(y ~ x) bai_perron(y, x, max_breaks=, trim=) Bai-Perron multiple breaks: global DP partition, sequential supF(l+1|l) at 5%, per-regime OLS, Bai (1997) break-date CIs. x is T x q with all coefficients switching (include the constant).
strucchange::Fstats, sctest(type="supF") sup_f_test(y, x, trim=) Andrews-Quandt sup-F unknown-break test; Hansen (1997) p-value and the full f_path.
Chow test (strucchange::sctest(type="Chow")) chow_test(y, x, split) F-test at a known 0-indexed split.
strucchange::efp(type="OLS-CUSUM") + sctest cusum_test(y, x) Brown-Durbin-Evans CUSUM path with 5% bounds.
lmtest::resettest reset_test(y, x, max_power=) Ramsey RESET functional-form F-test.
lmtest::bptest, skedastic::white heteroskedasticity_test(y, x, test="breusch_pagan"/"white") Breusch-Pagan / White; x is T x k with a constant.

Univariate models and volatility — forecast, rugarch, rmgarch, MSwM

R tsecon Notes
forecast::Arima(y, order=c(p,d,q)) arima_fit(y, p, d, q, constant=True) Exact-MLE.
forecast::Arima(y, order=, seasonal=c(P,D,Q)) arima_fit(y, p, d, q, seasonal=(P, D, Q, s)) Multiplicative SARIMA on the same exact-MLE engine; the airline model is arima_fit(np.log(air), p=0, d=1, q=1, seasonal=(0, 1, 1, 12), constant=False). Validated against SARIMAX(..., simple_differencing=True).
forecast::auto.arima(y) auto_arima(y, seasonal_period=, ic="aicc", stepwise=True) The Hyndman-Khandakar (2008) algorithm itself: nsdiffs for D, ndiffs for d, then the stepwise neighborhood search (stepwise=False for the exhaustive grid) at those fixed differencing orders.
forecast::ndiffs(y), nsdiffs(y) ndiffs(y, test="kpss"), nsdiffs(y, period) The differencing advisors, with the per-order evidence (steps) and the stop reason, not just the count.
stats::stl(y), forecast::mstl(y) stl(y, period, ...), mstl(y, periods) Cleveland et al. (1990) STL and the Bandara-Hyndman-Bergmeir multi-seasonal iteration; both pinned elementwise to statsmodels at 1e-8. seasonal_strength(y, period) is the Wang-Smith-Hyndman feature behind nsdiffs.
forecast::thetaf(y, h) theta_forecast(y, steps=h, period=) The Theta method.
forecast::accuracy(f, y) accuracy(actual, forecast, insample=, period=) ME/RMSE/MAE/MAPE/sMAPE/MASE/RMSSE.
forecast::dm.test(e1, e2) dm_test(e1, e2, h=1, loss="squared") HLN small-sample correction.
rugarch::ugarchfit(spec, y) garch_fit(y, vol="garch"/"gjr"/"egarch", p, o, q, dist=) GJR via vol="gjr" (o sets the asymmetry order there; o > 0 with vol="garch" raises). se_robust = Bollerslev-Wooldridge.
rmgarch::dccfit(...) dcc_garch(returns) Engle (2002) DCC; returns is T x k.
ccgarch, constant-correlation ccc_garch(returns) Bollerslev (1990) CCC.
GAS::UniGASFit(...) gas_volatility(y, density="gaussian"/"student_t") Creal-Koopman-Lucas score-driven volatility.
MSwM::msmFit, MSGARCH markov_switching_ar(y, k_regimes, order, switching_variance=) Hamilton EM; regimes, transition, durations.

Threshold and smooth-transition models — tsDyn

The whole tsDyn core — SETAR, LSTAR/ESTAR, TVAR, TVECM, and each package's linearity test — is callable today. The univariate pair shipped earlier; the threshold VAR, threshold VECM and STAR blocks are 0.7.0.

R tsecon Notes
tsDyn::setar(y, m=p, thDelay=d) setar(y, p, delay=d, delays=None, trim=0.15) Two-regime SETAR (Tong-Lim 1980) by concentrated LS (Hansen 1997): per-regime params_low/params_high with SEs, the selected threshold, and — when delays is a list — the selected delay, all candidates sharing one common sample so the SSRs are comparable.
tsDyn::setarTest(y, m=p) setar_test(y, p, n_boot=499, seed=0) Hansen (1996) sup-F linearity test. The threshold is an unidentified nuisance parameter under the null, so no chi-squared p-value is ever reported — the p-value comes from the fixed-regressor wild bootstrap, seeded and bit-reproducible at any thread count.
tsDyn::lstar(y, m=p, thDelay=d) star(y, p, model="lstar"/"estar", delay=d) Smooth transition (Terasvirta 1994) by concentrated NLS: an n_gamma x n_c grid then Nelder-Mead. gamma is RAW — tsDyn's convention, no standardization — and gamma_standardized is Terasvirta's scale-free version; converged, gamma_at_boundary and se_valid are honesty flags, not decoration.
(score a published (gamma, c)) star_eval(y, p, gamma, c, model=) The concentrated fit at FIXED transition parameters, with Gauss-Newton SEs — how you compare against a published parameterization without re-running someone else's optimizer.
tsDyn linearity + model-selection battery star_test(y, p, delay=) Terasvirta's LM3 test (Luukkonen-Saikkonen-Terasvirta 1988) plus the H03/H02/H01 sequence that chooses LSTAR vs ESTAR, and a suggested verdict. The auxiliary regression is linear, so the null distribution is standard — no bootstrap.
tsDyn::TVAR(data, lag=p, thDelay=d) threshold_var(data, p, threshold_index=, delay=d) Two-regime threshold VAR (Tsay 1998; Lo-Zivot 2001), concentrated LS minimizing log_det_sigma. data is T x k; the threshold variable is y[threshold_index]_{t-delay}.
tsDyn::TVAR.LRtest threshold_var_test(data, p, n_boot=499, seed=0) Robust score-form sup-Wald with Eicker-White covariance at the null, p-valued by the Hansen (1996) fixed-regressor bootstrap. Not the same statistic as TVAR.LRtest (a sup-LR with a residual bootstrap), so the numbers are not comparable across the two — only the verdict is.
tsDyn::TVECM(data, lag=) threshold_vecm(data, k_ar_diff, beta=None) Hansen-Seo (2002) threshold cointegration: concentrated Gaussian MLE on a (beta, gamma) grid, the error-correction term driving the regime split. beta=None estimates the cointegrating vector — bivariate only; pass beta= for k > 2.
tsDyn::TVECM.HStest hansen_seo_test(data, k_ar_diff, n_boot=499, seed=0) The Hansen-Seo sup-LM test of linear against threshold cointegration, their own fixed-regressor bootstrap. Again no chi-squared p-value: the Davies problem applies.

How this block is graded — read this before you compare numbers. tsDyn could not be installed in the fixture container (CRAN is unreachable through its egress proxy), so it never ran and there is no reference run behind any row in this section. What carries these functions instead is (i) closed forms transcribed from the published papers and pinned at 1e-10 against an independent NumPy implementation — 1e-8 for the estimated-beta threshold-VECM cases, where an eigensolver is in the path — and (ii) seeded Monte-Carlo size, power and parameter recovery: threshold-VECM null size 0.100 at T=150 falling to 0.065 at T=400, threshold-VAR 0.100 → 0.085 over the same range, STAR LM3-F size 0.060/0.028 at T=200/500 with power 0.81 (LSTAR) / 0.91 (ESTAR). The tsDyn reference run is named follow-up work. Until it lands, read these rows as "same estimand, published algorithm, independently transcribed" — not as "validated against R" or "matched to tsDyn". Note also that even with tsDyn runnable, point estimates would agree only at grid resolution, and TVAR.LRtest is a different statistic (sup-LR, residual bootstrap) from the sup-Wald here. The per-function grades are in the validation matrix.

Mixed frequency and nowcasting — midasr, nowcasting

R tsecon Notes
midasr::midas_r(y ~ ..., nbeta/nealmon) weighted_midas(y, hf_lags, scheme="beta"/"exp_almon") NLS-estimated restricted weights; hf_lags is nobs x K.
midasr::midas_u / U-MIDAS umidas(y, hf_lags, se_type="hac") Unrestricted mixed-frequency regression.
midasr::nbeta, nealmon weight builders midas_weights(scheme, theta1, theta2, k) The weight vector alone.
nowcasting::nowcast(...) (DFM) dfm_nowcast(data, n_factors, factor_order) Two-step DGR (2011); handles the ragged edge (NaNs).
nowcasting news decomposition dfm_news(old_vintage, new_vintage, target_series, ...) Banbura-Modugno (2014) per-datapoint news contributions.

Panel time series — plm, xtmg-style estimators

R's panel workflow (plm) uses a long pdata.frame. tsecon instead takes a list of per-unit arrays: ys is a list of response vectors, xs a list of T_i x k regressor matrices — which is what you get from split(df, df$id). The alternative panel_fe/panel_lp layout is a dense N x T outcome with a k x N x T regressor tensor.

R tsecon Notes
plm::pmg(..., model="mg") panel_mean_group(ys, xs, method="mg") Pesaran-Smith (1995) mean group: per-unit OLS, then average.
plm::pmg(..., model="pmg") panel_pmg(ys, xs) Pooled Mean Group ARDL(1,1) (Pesaran-Shin-Smith 1999); pools the long-run coef by ML.
xtmg/CCEMG (Pesaran 2006) panel_mean_group(ys, xs, method="cce") Common-correlated-effects mean group.
plm::plm(..., model="within") panel_fe(outcome, regressors, se_type=) Fixed effects; outcome is N x T, regressors is k x N x T.
plm + vcovSCC (Driscoll-Kraay) panel_fe(..., se_type="driscoll_kraay") Same SE, one argument.
Panel VAR (panelvar) mean_group_var(entities, lags, horizon) Pesaran-Smith mean-group panel VAR over per-entity T_i x k matrices.
plm::purtest (IPS, LLC, Fisher) panel_unit_root(data, test="ips"/"llc"/"fisher") Levin-Lin-Chu, Im-Pesaran-Shin and the Fisher-type (Maddala-Wu / Choi) combinations. data is a balanced N x T array (a row per unit) or a list of per-unit series — unbalanced is fine for "ips"/"fisher". Conventions follow plm::purtest; the plm anchor block covers 3 of the 12 fixture cases at 1e-4, the tighter tolerances elsewhere being against an independent transcription.
Mei-Sheng-Shi's panelLP.R (split-panel jackknife) panel_lp(..., bias_correction="spj") Split-panel jackknife for the short-T panel-LP bias, with adjusted-score cluster / Driscoll-Kraay SEs. Transcribed from the R script (which commits no numeric outputs), then Monte-Carlo checked: bias cut 15x at T=20, coverage 0.74 → 0.82 — nominal is not reached at T=20, and that is documented rather than smoothed over.

Realized volatility, connectedness, term structure

R tsecon Notes
highfrequency::rCov, rBPCov realized_measures(returns) RV, bipower variation, jump component (BNS 2004).
HARModel::HARestimate har_rv(rv, variant="level"/"log"/"sqrt") HAR-RV (Corsi 2009) with HAC SEs.
highfrequency::medRQ, rQuar realized_quarticity, tripower_quarticity Integrated-quarticity estimators.
highfrequency::BNSjumptest bns_jump_test(returns) BNS ratio jump test.
TTR/highfrequency range vol realized_range(high, low, method="parkinson"/"garman_klass") From OHLC bars.
frequencyConnectedness, ConnectednessApproach connectedness(data, lags, horizon) Diebold-Yilmaz spillover table (GFEVD).
YieldCurve::Nelson.Siegel nelson_siegel(maturities, yields, optimal_lambda=) Level/slope/curvature + fit.
YieldCurve::Svensson svensson(maturities, yields, lambda1, lambda2) Four-factor, nests Nelson-Siegel.
YieldCurve dynamic NS (Diebold-Li) dynamic_ns(panel, maturities, decay) Factor series + one-step forecast.

GMM and penalized regression — gmm, glmnet

R tsecon Notes
gmm::gmm(g, x, ...) linear IV iv_gmm(x, z, y, method="2step"/"iterated", weight="robust"/"hac") Hansen (1982); over-identified fits report the Hansen J.
gmm::gmm(...) nonlinear moments gmm_nonlinear(moments_fn, initial, weight=) Custom moment function as a Python callback.
AER::ivreg(y ~ x \| z) (2SLS) iv_gmm(x, z, y, method="2sls") The 2SLS special case.
glmnet(x, y, alpha=1) (lasso) lasso(x, y, alpha) / lasso_path(x, y) lasso_path returns the full path with AIC/BIC selection.
glmnet(x, y, alpha=a) (elastic net) elastic_net(x, y, alpha, l1_ratio) scikit-learn objective.
glmnet(x, y, alpha=0) (ridge) ridge(x, y, alpha) Closed form.
adaptive lasso (glmnet + weights) adaptive_lasso(x, y, alpha, gamma=) Zou (2006) oracle-property weights.

Quantile regression and Growth-at-Risk — quantreg

R tsecon Notes
quantreg::rq(y ~ x, tau=) quantile_regression(y, x, taus=) IRLS check-loss with Powell kernel-sandwich SEs; include the constant column in x.
Quantile local projections — no standard R package quantile_lp(y, shock, taus, horizons) Per-tau IRFs irf[tau][h] with Powell-sandwich SEs. tsecon-native.
Conditional-quantile Growth-at-Risk — no single-call R equivalent growth_at_risk(y, conditions, horizon, taus) Adrian-Boyarchenko-Giannone (2019); current is the latest GaR read, with optional CFG monotone rearrangement.

Filters and spectra — mFilter, neverhpfilter

R tsecon Notes
mFilter::hpfilter(y, freq) hp_filter(y, lamb, one_sided=)
mFilter::bkfilter(y) bk_filter(y, low, high, k)
mFilter::cffilter(y) cf_filter(y, low, high, drift)
neverhpfilter::yth_filter hamilton_filter(y, h=8, p=4) Hamilton (2018) regression filter.
spectrum(y), stats::spec.pgram periodogram(x), welch(x), coherence(x, y) Match SciPy's spectral estimators.

Worked translations

Six you can run. The R call is shown as a comment.

urca::ca.jojohansen + vecm

import numpy as np, tsecon
rng = np.random.default_rng(7)
trend = np.cumsum(rng.standard_normal(200))           # one shared stochastic trend
data = np.column_stack([trend + rng.standard_normal(200) for _ in range(3)])

jo = tsecon.johansen(data, k_ar_diff=1)               # urca::ca.jo(data, type="trace")
print(np.round(jo["trace_stat"], 2), jo["rank_trace_5pct"])

# deterministic="co" (unrestricted constant) matches the convention the rank
# test above assumes; the "n" default is the no-deterministic model instead.
vm = tsecon.vecm(data, k_ar_diff=1, coint_rank=1, deterministic="co")
print(np.round(np.asarray(vm["beta"]).ravel(), 3))    # the cointegrating vector

BVAR::bvarbvar_fit + bvar_irf_draws

import numpy as np, tsecon
rng = np.random.default_rng(5)
data = rng.standard_normal((200, 3))

bv = tsecon.bvar_fit(data, lags=2, lambda1=0.2)       # BVAR::bvar(data, lags=2)
draws = tsecon.bvar_irf_draws(data, lags=2, horizon=12,
                              n_draws=500, seed=1)      # [draw, h, var, shock]
med = np.median(np.asarray(draws), axis=0)             # posterior-median IRF surface
print(round(bv["log_marginal_likelihood"], 2), med.shape)

rmgarch::dccfitdcc_garch

import numpy as np, tsecon
def garch_sim(seed, T=1000):                           # a clustered return series
    rng = np.random.default_rng(seed)
    e = rng.standard_normal(T); h = np.empty(T); r = np.empty(T)
    h[0] = 0.5; r[0] = np.sqrt(h[0]) * e[0]
    for t in range(1, T):
        h[t] = 0.05 + 0.08 * r[t-1]**2 + 0.90 * h[t-1]
        r[t] = np.sqrt(h[t]) * e[t]
    return r

ret = np.column_stack([garch_sim(s) for s in (6, 7, 8)])
dcc = tsecon.dcc_garch(ret)                            # rmgarch::dccfit(spec, ret)
print(round(dcc["a"], 4), round(dcc["b"], 4))

midasr::midas_rweighted_midas

import numpy as np, tsecon
rng = np.random.default_rng(8)
hf = rng.standard_normal((120, 3))                     # three high-frequency lags
y = hf @ np.array([0.6, 0.3, 0.1]) + rng.standard_normal(120)

wm = tsecon.weighted_midas(y, hf, scheme="beta")       # midasr::midas_r(y ~ ..., nbeta)
print(round(wm["slope"], 3), round(wm["rsquared"], 3))

plm::pmgpanel_pmg (and mean group)

import numpy as np, tsecon
rng = np.random.default_rng(9)
ys = [rng.standard_normal(40) for _ in range(15)]      # split(df, df$id) -> per-unit
xs = [rng.standard_normal((40, 2)) for _ in range(15)]

pmg = tsecon.panel_pmg(ys, xs)                         # plm::pmg(..., model="pmg")
mg = tsecon.panel_mean_group(ys, xs, method="mg")      # plm::pmg(..., model="mg")
print(np.round(pmg["theta"], 3), np.round(mg["coef"], 3))

tsDyn::TVECMthreshold_vecm + hansen_seo_test

import numpy as np, tsecon
rng = np.random.default_rng(3)
n = 400
x = np.cumsum(rng.standard_normal(n))                  # the common stochastic trend
w = np.zeros(n)                                        # a band-threshold spread: it
for t in range(1, n):                                  # barely corrects inside |w|<=1
    adj = -0.02 * w[t-1] if abs(w[t-1]) <= 1.0 else -0.35 * w[t-1]
    w[t] = w[t-1] + adj + 0.5 * rng.standard_normal()
data = np.column_stack([x + w, x])

tv = tsecon.threshold_vecm(data, k_ar_diff=1)          # tsDyn::TVECM(data, lag=1)
hs = tsecon.hansen_seo_test(data, k_ar_diff=1,
                            n_boot=199, seed=0)        # tsDyn::TVECM.HStest(...)
print(round(tv["threshold"], 3), np.round(np.asarray(tv["beta"]).ravel(), 3))
print(round(hs["stat"], 2), hs["p_value"])             # sup-LM, bootstrap p-value

What R has that tsecon does not (yet)

R's long tail is deep, and a short list of it is still roadmap:

  • Explicit short-run A/B SVAR restrictions (vars::SVAR's Amat/Bmat). Long-run Blanchard-Quah is long_run_svar, and zero-and-sign set identification is zero_sign_svar, but the exactly-identified A/B system is not shipped.
  • Variance-model statistical identificationsvars::id.garch and id.st. The two-regime id.cv case is hetero_svar and the non-Gaussian case is nongaussian_svar.
  • Stochastic-volatility BVAR priors. The conjugate Minnesota-NIW (bvar_fit), the hierarchical ML-II selection (bvar_hierarchical) and SSVS (bvar_ssvs) all ship; time-varying volatility in the prior does not.
  • Classical decompose()-style seasonal decomposition and TBATS/Prophet-style seasonal forecasters. stl, mstl, seasonal_strength, nsdiffs and auto_arima's seasonal search do ship.
  • General unobserved-components models in the KFAS/dlm sense. local_level_smooth and dcs_local_level are the shipped state-space pieces.
  • The fuller panelvar GMM toolkit. mean_group_var is the mean-group panel VAR only; panel_unit_root, panel_pmg, panel_mean_group, panel_fe and panel_lp cover the rest of the plm surface this page maps.

That is the whole list. Everything else this section used to name has shipped, and the tables above are where it now lives: auto_arima, seasonal arima_fit(seasonal=...), phillips_perron, phillips_ouliaris, engle_granger, long_run_svar, hetero_svar, nongaussian_svar, bvar_hierarchical, bvar_ssvs, panel_unit_root, stl/mstl, and the whole tsDyn core — setar, setar_test, star, star_eval, star_test, threshold_var, threshold_var_test, threshold_vecm, hansen_seo_test.

Where tsecon repays the switch is speed and coherence: one library instead of a dozen, a single shared HAC/bootstrap core, reproducible parallel RNG, the tsDyn nonlinear core beside markov_switching_ar and lp_state, and the modern macro-structural methods (lp, sign_restricted_svar, dfm_nowcast, favar, connectedness) delivered under one calling grammar.

See also the statsmodels and Stata guides, and the cross-package Rosetta glossary.