{"id":14066669,"url":"https://github.com/SebKrantz/dfms","last_synced_at":"2025-07-29T23:32:02.984Z","repository":{"id":50701190,"uuid":"399755644","full_name":"SebKrantz/dfms","owner":"SebKrantz","description":"Dynamic Factor Models for R","archived":false,"fork":false,"pushed_at":"2025-06-17T00:28:53.000Z","size":32761,"stargazers_count":37,"open_issues_count":0,"forks_count":10,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-17T01:28:13.373Z","etag":null,"topics":["dynamic-factor-models","rstats","time-series"],"latest_commit_sha":null,"homepage":"https://sebkrantz.github.io/dfms/","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SebKrantz.png","metadata":{"files":{"readme":"README.md","changelog":"NEWS.md","contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":"codemeta.json","zenodo":null}},"created_at":"2021-08-25T09:04:15.000Z","updated_at":"2025-06-17T00:22:50.000Z","dependencies_parsed_at":"2024-06-09T13:39:30.223Z","dependency_job_id":"12e14935-2cfa-4e66-aed6-92cecf70e9d3","html_url":"https://github.com/SebKrantz/dfms","commit_stats":{"total_commits":245,"total_committers":1,"mean_commits":245.0,"dds":0.0,"last_synced_commit":"dd930a639e5216b30565339995b93270ece918ab"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/SebKrantz/dfms","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SebKrantz%2Fdfms","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SebKrantz%2Fdfms/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SebKrantz%2Fdfms/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SebKrantz%2Fdfms/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SebKrantz","download_url":"https://codeload.github.com/SebKrantz/dfms/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SebKrantz%2Fdfms/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267780014,"owners_count":24143201,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-29T02:00:12.549Z","response_time":2574,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dynamic-factor-models","rstats","time-series"],"created_at":"2024-08-13T07:05:12.626Z","updated_at":"2025-07-29T23:32:02.967Z","avatar_url":"https://github.com/SebKrantz.png","language":"R","readme":"# **dfms**: Dynamic Factor Models for R\n\u003c!-- badges: start --\u003e\n[![Status at rOpenSci Software Peer Review](https://badges.ropensci.org/556_status.svg)](https://github.com/ropensci/software-review/issues/556)\n[![R-CMD-check](https://github.com/SebKrantz/dfms/workflows/R-CMD-check/badge.svg)](https://github.com/SebKrantz/dfms/actions)\n[![dfms status badge](https://sebkrantz.r-universe.dev/badges/dfms)](https://sebkrantz.r-universe.dev)\n[![CRAN status](https://www.r-pkg.org/badges/version/dfms)](https://cran.r-project.org/package=dfms) \n[![cran checks](https://badges.cranchecks.info/worst/dfms.svg)](https://cran.r-project.org/web/checks/check_results_dfms.html)\n![downloads per month](https://cranlogs.r-pkg.org/badges/dfms?color=blue)\n![downloads](https://cranlogs.r-pkg.org/badges/grand-total/dfms?color=blue)\n[![Codecov test coverage](https://codecov.io/gh/SebKrantz/dfms/branch/main/graph/badge.svg)](https://app.codecov.io/gh/SebKrantz/dfms?branch=main)\n[![minimal R version](https://img.shields.io/badge/R%3E%3D-3.5.0-6666ff.svg)](https://cran.r-project.org/)\n[![dependencies](https://tinyverse.netlify.app/badge/dfms)](https://CRAN.R-project.org/package=dfms)\n\u003c!-- [![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) --\u003e\n\u003c!-- badges: end\n\n\u003c!-- **NOTE**: This package is under [rOpenSci Statistical Software Peer Review](https://stats-devguide.ropensci.org/). Peer review might result in changes to the API. --\u003e\n\u003c!--\nThe package is fully functional though, and you are very welcome to install it using `remotes::install_github(\"SebKrantz/dfms\")` and give feedback. --\u003e\n\n*dfms* provides efficient estimation of Dynamic Factor Models via the EM Algorithm. Factors are assumed to follow a stationary VAR \n  process of order `p`. Estimation can be done in 3 different ways following:\n\n- Doz, C., Giannone, D., \u0026 Reichlin, L. (2011). A two-step estimator for large approximate dynamic factor models based on Kalman filtering. *Journal of Econometrics, 164*(1), 188-205. \u003cdoi:10.1016/j.jeconom.2011.02.012\u003e \n\n- Doz, C., Giannone, D., \u0026 Reichlin, L. (2012). A quasi-maximum likelihood approach for large, approximate dynamic factor models. *Review of Economics and Statistics, 94*(4), 1014-1024. \u003cdoi:10.1162/REST_a_00225\u003e\n\n- Banbura, M., \u0026 Modugno, M. (2014). Maximum likelihood estimation of factor models on datasets with arbitrary pattern of missing data. *Journal of Applied Econometrics, 29*(1), 133-160. \u003cdoi:10.1002/jae.2306\u003e\n\nThe default is `em.method = \"auto\"`, which chooses `\"BM\"` following Banbura \u0026 Modugno (2014) with missing data or mixed frequency, and `\"DGR\"` following Doz, Giannone \u0026 Reichlin (2012) otherwise. Using `em.method = \"none\"` generates Two-Step estimates following Doz, Giannone \u0026 Reichlin (2011). This is extremely efficient on bigger datasets. PCA and Two-Step estimates are also reported in EM-estimation. All methods support missing data, but `em.method = \"DGR\"` does not model them in EM iterations.\n\nThe package is currently stable, but functionality may expand in the future. In particular, mixed-frequency estimation with autoregressive errors is planned for the near future, and generation of the 'news' may be added in the further future. \n\n\n### Comparison with Other R Packages\n\n*dfms* is intended to provide a simple, numerically robust, and computationally efficient baseline implementation of (linear Gaussian) Dynamic Factor Models for R, allowing straightforward application to various contexts such as time series dimensionality reduction and forecasting. The implementation is based on efficient C++ code, making *dfms* orders of magnitude faster than packages that can be used to fit dynamic factor models such as [*MARSS*](\u003chttps://CRAN.R-project.org/package=MARSS\u003e), or [*nowcasting*](\u003chttps://github.com/nmecsys/nowcasting\u003e) and [*nowcastDFM*](\u003chttps://github.com/dhopp1/nowcastDFM\u003e) geared to mixed-frequency nowcasting applications - supporting blocking of variables into different groups for which factors are to be estimated and evaluation of news content. For large-scale nowcasting models the [`DynamicFactorMQ`](https://www.statsmodels.org/dev/generated/statsmodels.tsa.statespace.dynamic_factor_mq.DynamicFactorMQ.html) class in the `statsmodels` Python library is probably the most robust implementation - see the [example](http://www.chadfulton.com/topics/statespace_large_dynamic_factor_models.html) by Chad Fulton.   \u003c!-- , and EM adjustments for variables at different frequencies. *dfms* with `em.method = \"BM\"` does allow mixed-frequency data but performs no specific adjustments for the frequency of the data^[All series are weighted equally, and the prevalence of missing values in lower-frequency series downweights them. To remedy this lower frequency series could be included multiple times in the dataset e.g. include a quarterly series 3 times in a monthly dataset.]. *dfms* currently also does not allow residual autocorrelation in the estimation (i.e. it cannot estimate *approximate factor models*), but the addition of this feature is planned. --\u003e\nThe *dfms* package is not intended to fit more general forms of the state space model like [*MARSS*](\u003chttps://CRAN.R-project.org/package=MARSS\u003e).\n\n\u003c!-- or advanced specifications of Dynamic Factor Models tailored to mixed-frequency nowcasting applications such as [*nowcasting*](\u003chttps://github.com/nmecsys/nowcasting\u003e) and [*nowcastDFM*](\u003chttps://github.com/dhopp1/nowcastDFM\u003e). Such software could however benefit from the functions and methods provided in *dfms*, most notably *dfms* exports stationary Kalman Filters and Smoothers used in nowcasting applications, that are noticeably faster than the more general implementations provided by the [*FKF*](\u003chttps://CRAN.R-project.org/package=FKF\u003e) package. --\u003e\n\u003c!-- Estimation with *dfms* also requires stationary data of a single frequency, and assumes time-invariant system matrices and classical assumptions (i.e. the 'exact factor model', assuming away residual autocorrelation in the observation equation). --\u003e\n\n### Installation \n\n```r\n# CRAN\ninstall.packages(\"dfms\")\n\n# Development Version\ninstall.packages('dfms', repos = c('https://sebkrantz.r-universe.dev', 'https://cloud.r-project.org'))\n\n```\n\n### Usage Example \n\n\n```r\nlibrary(dfms)\n\n# Fit DFM with 6 factors and 3 lags in the transition equation\nmod \u003c- DFM(diff(BM14_M), r = 6, p = 3) \n```\n\n```\n## Converged after 32 iterations.\n```\n\n```r\n# 'dfm' methods\nsummary(mod)\n```\n\n```\n## Dynamic Factor Model: n = 92, T = 356, r = 6, p = 3, %NA = 25.8366\n## \n## Call:  DFM(X = diff(BM14_M), r = 6, p = 3)\n## \n## Summary Statistics of Factors [F]\n##       N     Mean   Median      SD       Min      Max\n## f1  356  -0.1189   0.4409  4.0228  -22.9164   7.8513\n## f2  356  -0.4615  -0.3476  2.9201   -9.0973  10.7003\n## f3  356  -0.0173   0.0377  2.2719   -8.5067   7.3009\n## f4  356   -0.007  -0.1338  1.9378   -9.5052   9.3673\n## f5  356    0.237   0.1091  2.0857   -8.7252   9.6715\n## f6  356  -0.8361   -0.304  3.1406  -11.6611  15.4897\n## \n## Factor Transition Matrix [A]\n##       L1.f1    L1.f2     L1.f3    L1.f4    L1.f5    L1.f6    L2.f1    L2.f2    L2.f3\n## f1  0.53029 -0.53009  0.367302  0.04607 -0.06351  0.10310  0.02457  0.11673 -0.12638\n## f2 -0.28380  0.07421 -0.032292  0.29741 -0.10094  0.21989  0.09958 -0.09149  0.06708\n## f3  0.17607  0.12979  0.378798 -0.06662 -0.12236  0.06685 -0.08068  0.09101 -0.22232\n## f4  0.02711  0.08936  0.004643  0.37159  0.12100 -0.02763  0.01234 -0.05147  0.02195\n## f5 -0.26227 -0.03469 -0.046294  0.12712  0.26847  0.03141  0.06400  0.01971  0.04806\n## f6  0.08251  0.17619 -0.013374 -0.08731 -0.03875  0.27812 -0.01662  0.04877  0.02279\n##       L2.f4     L2.f5    L2.f6    L3.f1    L3.f2    L3.f3    L3.f4    L3.f5    L3.f6\n## f1  0.23135  0.117184  0.21941  0.18478  0.02259 -0.03719 -0.07236 -0.03026 -0.12606\n## f2 -0.09768 -0.043057  0.08489  0.21107  0.16261  0.03057  0.04835  0.12249  0.13357\n## f3  0.09799 -0.060666 -0.18028 -0.02773  0.01798  0.10143 -0.12420  0.04207 -0.07011\n## f4  0.01266  0.050912  0.05144 -0.05601  0.04665  0.05710 -0.11412 -0.05680 -0.01609\n## f5 -0.03965 -0.009952 -0.18471  0.08332 -0.04640 -0.02047  0.02458  0.16397  0.07820\n## f6  0.01163 -0.100859  0.07152  0.00792  0.06071  0.11381  0.02520 -0.17897  0.30328\n## \n## Factor Covariance Matrix [cov(F)]\n##           f1        f2        f3        f4        f5        f6\n## f1  16.1832   -0.4329    0.2483   -0.8224*  -1.7708*   0.7702 \n## f2  -0.4329    8.5272    0.0051    0.2954   -0.2114    4.2080*\n## f3   0.2483    0.0051    5.1614   -0.1851   -0.3979    0.2979 \n## f4  -0.8224*   0.2954   -0.1851    3.7550    0.4344*   0.2211 \n## f5  -1.7708*  -0.2114   -0.3979    0.4344*   4.3503   -1.9785*\n## f6   0.7702    4.2080*   0.2979    0.2211   -1.9785*   9.8634 \n## \n## Factor Transition Error Covariance Matrix [Q]\n##         u1      u2      u3      u4      u5      u6\n## u1  7.2142  0.1151 -0.8208 -0.4379  0.4110 -0.1206\n## u2  0.1151  4.8724  0.1076 -0.1438  0.1418  0.1759\n## u3 -0.8208  0.1076  4.0584 -0.0788  0.0163  0.0038\n## u4 -0.4379 -0.1438 -0.0788  3.0003  0.2562  0.0243\n## u5  0.4110  0.1418  0.0163  0.2562  2.8410 -0.1031\n## u6 -0.1206  0.1759  0.0038  0.0243 -0.1031  2.9284\n## \n## Summary of Residual AR(1) Serial Correlations\n##    N     Mean   Median      SD      Min     Max\n##   92  -0.0644  -0.1024  0.2702  -0.5113  0.6674\n## \n## Summary of Individual R-Squared's\n##    N    Mean  Median      SD     Min     Max\n##   92  0.4556  0.4069  0.3041  0.0112  0.9989\n```\n\n```r\nplot(mod)\n```\n\n\u003cdiv class=\"figure\"\u003e\n\u003cimg src=\"https://raw.githubusercontent.com/SebKrantz/dfms/main/misc/figure/unnamed-chunk-1-1.png\" alt=\"plot of chunk unnamed-chunk-1\" width=\"100%\" /\u003e\n\u003c/div\u003e\n\n```r\nas.data.frame(mod) |\u003e head()\n```\n\n```\n##   Method Factor Time      Value\n## 1    PCA     f1    1  0.8445713\n## 2    PCA     f1    2  0.5259228\n## 3    PCA     f1    3 -1.2107116\n## 4    PCA     f1    4 -1.5399532\n## 5    PCA     f1    5 -0.4631786\n## 6    PCA     f1    6  0.2399304\n```\n\n```r\n# Forecasting 12 periods ahead\nfc \u003c- predict(mod, h = 12)\n\n# 'dfm_forecast' methods\nplot(fc, xlim = c(320, 370))\n```\n\n\u003cdiv class=\"figure\"\u003e\n\u003cimg src=\"https://raw.githubusercontent.com/SebKrantz/dfms/main/misc/figure/unnamed-chunk-1-2.png\" alt=\"plot of chunk unnamed-chunk-1\" width=\"100%\" /\u003e\n\u003c/div\u003e\n\n```r\nas.data.frame(fc) |\u003e head()\n```\n\n```\n##   Variable Time Forecast      Value\n## 1       f1    1    FALSE   4.179331\n## 2       f1    2    FALSE  -1.368577\n## 3       f1    3    FALSE -12.845157\n## 4       f1    4    FALSE -14.562265\n## 5       f1    5    FALSE  -7.791254\n## 6       f1    6    FALSE  -1.254970\n```\n","funding_links":[],"categories":["R"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSebKrantz%2Fdfms","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FSebKrantz%2Fdfms","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSebKrantz%2Fdfms/lists"}