From 5f97a1a7c7b11e303aa60cb2e9d07ef4040125bb Mon Sep 17 00:00:00 2001 From: Matthieu Gomez Date: Wed, 21 Jan 2026 11:35:12 -0500 Subject: [PATCH 1/8] Enhance README with model inspection methods Added methods to inspect results from the reg() model object and clarified the need for a dataframe in certain functions. --- README.md | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index bf1e92b..2f8f514 100755 --- a/README.md +++ b/README.md @@ -82,16 +82,37 @@ reg(df, @formula(Sales ~ NDI + fe(State) + fe(Year)), Vcov.cluster(:State), weig ## Output -`reg` returns a light object. It is composed of - - - the vector of coefficients & the covariance matrix (use `coef`, `coefnames`, `vcov` on the output of `reg`) - - a boolean vector reporting rows used in the estimation - - a set of scalars (number of observations, the degree of freedoms, r2, etc) - -Methods such as `predict`, `residuals` are still defined but require to specify a dataframe as a second argument. The problematic size of `lm` and `glm` models in R or Julia is discussed [here](http://www.r-bloggers.com/trimming-the-fat-from-glm-models-in-r/), [here](https://blogs.oracle.com/R/entry/is_the_size_of_your), [here](http://stackoverflow.com/questions/21896265/how-to-minimize-size-of-object-of-class-lm-without-compromising-it-being-passe) [here](http://stackoverflow.com/questions/15260429/is-there-a-way-to-compress-an-lm-class-for-later-prediction) (and for absurd consequences, [here](http://stackoverflow.com/questions/26010742/using-stargazer-with-memory-greedy-glm-objects) and [there](http://stackoverflow.com/questions/22577161/not-enough-ram-to-run-stargazer-the-normal-way)). +The model object returned by `reg()` is lightweight. The following methods can be used to inspect the results +``` +# Coefficients +StatsAPI.coef(m::FixedEffectModel) +StatsAPI.vcov(m::FixedEffectModel) +StatsAPI.confint(m::FixedEffectModel) +StatsAPI.coefnames(m::FixedEffectModel) +StatsAPI.responsename(m::FixedEffectModel) +# Statistics +StatsAPI.nobs(m::FixedEffectModel) +StatsAPI.dof(m::FixedEffectModel) +StatsAPI.dof_residual(m::FixedEffectModel) +StatsAPI.r2(m::FixedEffectModel) +StatsAPI.islinear(m::FixedEffectModel) +StatsAPI.deviance(m::FixedEffectModel) +StatsAPI.nulldeviance(m::FixedEffectModel) +StatsAPI.rss(m::FixedEffectModel) +StatsAPI.mss(m::FixedEffectModel) +StatsAPI.loglikelihood(m::FixedEffectModel) +StatsAPI.nullloglikelihood(m::FixedEffectModel) +StatsAPI.adjr2(m::FixedEffectModel) +StatsAPI.coeftable +StatsModels.formula +# Prediction and residuals +StatsAPI.predict(m::FixedEffectModel, df) +StatsAPI.residuals(m::FixedEffectModel, df) +``` +The functions `StatsAPI.predict` and `StatsAPI.residuals` require a table (`df`) as a second argument because the object returned by `reg()` does not store the original dataset (to keep the model lightweight). For background on the tradeoff of storing the original data inside fitted model objects, see the following discussions: [1](http://www.r-bloggers.com/trimming-the-fat-from-glm-models-in-r/), [2](https://blogs.oracle.com/R/entry/is_the_size_of_your), [3](http://stackoverflow.com/questions/21896265/how-to-minimize-size-of-object-of-class-lm-without-compromising-it-being-passe), [4](http://stackoverflow.com/questions/15260429/is-there-a-way-to-compress-an-lm-class-for-later-prediction), [here](http://stackoverflow.com/questions/26010742/using-stargazer-with-memory-greedy-glm-objects), and [5](http://stackoverflow.com/questions/22577161/not-enough-ram-to-run-stargazer-the-normal-way). -You may use [RegressionTables.jl](https://github.com/jmboehm/RegressionTables.jl) to get publication-quality regression tables. +Finally, you may use [RegressionTables.jl](https://github.com/jmboehm/RegressionTables.jl) to get publication-quality regression tables. ## Performances From 17d41ca62d7cbbe9668d6057f6993aee0a6ff569 Mon Sep 17 00:00:00 2001 From: Matthieu Gomez Date: Wed, 21 Jan 2026 11:36:16 -0500 Subject: [PATCH 2/8] Bump version from 1.12.0 to 1.12.1 --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 81eadf6..7871fe4 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "FixedEffectModels" uuid = "9d5cd8c9-2029-5cab-9928-427838db53e3" -version = "1.12.0" +version = "1.12.1" [deps] DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" From 95e47b56e08ed1fc86c73f442b4ebbd573fab0ec Mon Sep 17 00:00:00 2001 From: Matthieu Gomez Date: Wed, 21 Jan 2026 11:36:58 -0500 Subject: [PATCH 3/8] Fix formatting for code block in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2f8f514..8c573fd 100755 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ reg(df, @formula(Sales ~ NDI + fe(State) + fe(Year)), Vcov.cluster(:State), weig ## Output The model object returned by `reg()` is lightweight. The following methods can be used to inspect the results -``` +```julia # Coefficients StatsAPI.coef(m::FixedEffectModel) StatsAPI.vcov(m::FixedEffectModel) From f52f24cac236c92e77749aef782c07de9132fbc8 Mon Sep 17 00:00:00 2001 From: Matthieu Gomez Date: Wed, 21 Jan 2026 11:37:19 -0500 Subject: [PATCH 4/8] Add additional StatsAPI functions to README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 8c573fd..a8a06b4 100755 --- a/README.md +++ b/README.md @@ -91,6 +91,7 @@ StatsAPI.vcov(m::FixedEffectModel) StatsAPI.confint(m::FixedEffectModel) StatsAPI.coefnames(m::FixedEffectModel) StatsAPI.responsename(m::FixedEffectModel) + # Statistics StatsAPI.nobs(m::FixedEffectModel) StatsAPI.dof(m::FixedEffectModel) @@ -106,6 +107,7 @@ StatsAPI.nullloglikelihood(m::FixedEffectModel) StatsAPI.adjr2(m::FixedEffectModel) StatsAPI.coeftable StatsModels.formula + # Prediction and residuals StatsAPI.predict(m::FixedEffectModel, df) StatsAPI.residuals(m::FixedEffectModel, df) From bc481f172cf35df61d82d96267ad9210b0811678 Mon Sep 17 00:00:00 2001 From: Matthieu Gomez Date: Wed, 21 Jan 2026 11:38:31 -0500 Subject: [PATCH 5/8] Remove StatsAPI prefix from method calls in README --- README.md | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index a8a06b4..5c3ea08 100755 --- a/README.md +++ b/README.md @@ -83,34 +83,34 @@ reg(df, @formula(Sales ~ NDI + fe(State) + fe(Year)), Vcov.cluster(:State), weig ## Output -The model object returned by `reg()` is lightweight. The following methods can be used to inspect the results +The model object returned by `reg()` is lightweight. The following methods from `StatsAPI`\ can be used to inspect the results ```julia # Coefficients -StatsAPI.coef(m::FixedEffectModel) -StatsAPI.vcov(m::FixedEffectModel) -StatsAPI.confint(m::FixedEffectModel) -StatsAPI.coefnames(m::FixedEffectModel) -StatsAPI.responsename(m::FixedEffectModel) +coef(m::FixedEffectModel) +vcov(m::FixedEffectModel) +confint(m::FixedEffectModel) +coefnames(m::FixedEffectModel) +responsename(m::FixedEffectModel) # Statistics -StatsAPI.nobs(m::FixedEffectModel) -StatsAPI.dof(m::FixedEffectModel) -StatsAPI.dof_residual(m::FixedEffectModel) -StatsAPI.r2(m::FixedEffectModel) -StatsAPI.islinear(m::FixedEffectModel) -StatsAPI.deviance(m::FixedEffectModel) -StatsAPI.nulldeviance(m::FixedEffectModel) -StatsAPI.rss(m::FixedEffectModel) -StatsAPI.mss(m::FixedEffectModel) -StatsAPI.loglikelihood(m::FixedEffectModel) -StatsAPI.nullloglikelihood(m::FixedEffectModel) -StatsAPI.adjr2(m::FixedEffectModel) -StatsAPI.coeftable -StatsModels.formula +nobs(m::FixedEffectModel) +dof(m::FixedEffectModel) +dof_residual(m::FixedEffectModel) +r2(m::FixedEffectModel) +islinear(m::FixedEffectModel) +deviance(m::FixedEffectModel) +nulldeviance(m::FixedEffectModel) +rss(m::FixedEffectModel) +mss(m::FixedEffectModel) +loglikelihood(m::FixedEffectModel) +nullloglikelihood(m::FixedEffectModel) +adjr2(m::FixedEffectModel) +coeftable(m::FixedEffectModel) +formula(m::FixedEffectModel) # Prediction and residuals -StatsAPI.predict(m::FixedEffectModel, df) -StatsAPI.residuals(m::FixedEffectModel, df) +predict(m::FixedEffectModel, df) +residuals(m::FixedEffectModel, df) ``` The functions `StatsAPI.predict` and `StatsAPI.residuals` require a table (`df`) as a second argument because the object returned by `reg()` does not store the original dataset (to keep the model lightweight). For background on the tradeoff of storing the original data inside fitted model objects, see the following discussions: [1](http://www.r-bloggers.com/trimming-the-fat-from-glm-models-in-r/), [2](https://blogs.oracle.com/R/entry/is_the_size_of_your), [3](http://stackoverflow.com/questions/21896265/how-to-minimize-size-of-object-of-class-lm-without-compromising-it-being-passe), [4](http://stackoverflow.com/questions/15260429/is-there-a-way-to-compress-an-lm-class-for-later-prediction), [here](http://stackoverflow.com/questions/26010742/using-stargazer-with-memory-greedy-glm-objects), and [5](http://stackoverflow.com/questions/22577161/not-enough-ram-to-run-stargazer-the-normal-way). From cf4b18761689028faaa08f02623088a23e82964e Mon Sep 17 00:00:00 2001 From: Matthieu Gomez Date: Wed, 21 Jan 2026 11:38:54 -0500 Subject: [PATCH 6/8] Update explanation for predict and residuals functions --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5c3ea08..3ddf2d4 100755 --- a/README.md +++ b/README.md @@ -112,7 +112,7 @@ formula(m::FixedEffectModel) predict(m::FixedEffectModel, df) residuals(m::FixedEffectModel, df) ``` -The functions `StatsAPI.predict` and `StatsAPI.residuals` require a table (`df`) as a second argument because the object returned by `reg()` does not store the original dataset (to keep the model lightweight). For background on the tradeoff of storing the original data inside fitted model objects, see the following discussions: [1](http://www.r-bloggers.com/trimming-the-fat-from-glm-models-in-r/), [2](https://blogs.oracle.com/R/entry/is_the_size_of_your), [3](http://stackoverflow.com/questions/21896265/how-to-minimize-size-of-object-of-class-lm-without-compromising-it-being-passe), [4](http://stackoverflow.com/questions/15260429/is-there-a-way-to-compress-an-lm-class-for-later-prediction), [here](http://stackoverflow.com/questions/26010742/using-stargazer-with-memory-greedy-glm-objects), and [5](http://stackoverflow.com/questions/22577161/not-enough-ram-to-run-stargazer-the-normal-way). +Note that the functions `predict` and `residuals` require a table (`df`) as a second argument because the object returned by `reg` does not store the original dataset (to keep the model lightweight). For background on the tradeoff of storing the original data inside fitted model objects, see the following discussions: [1](http://www.r-bloggers.com/trimming-the-fat-from-glm-models-in-r/), [2](https://blogs.oracle.com/R/entry/is_the_size_of_your), [3](http://stackoverflow.com/questions/21896265/how-to-minimize-size-of-object-of-class-lm-without-compromising-it-being-passe), [4](http://stackoverflow.com/questions/15260429/is-there-a-way-to-compress-an-lm-class-for-later-prediction), [here](http://stackoverflow.com/questions/26010742/using-stargazer-with-memory-greedy-glm-objects), and [5](http://stackoverflow.com/questions/22577161/not-enough-ram-to-run-stargazer-the-normal-way). Finally, you may use [RegressionTables.jl](https://github.com/jmboehm/RegressionTables.jl) to get publication-quality regression tables. From 0d9719e54b176e8035a9ce3019afc19d4813086d Mon Sep 17 00:00:00 2001 From: Matthieu Gomez Date: Wed, 21 Jan 2026 11:39:42 -0500 Subject: [PATCH 7/8] Fix formatting and update notes in README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3ddf2d4..a9bc2f2 100755 --- a/README.md +++ b/README.md @@ -112,9 +112,9 @@ formula(m::FixedEffectModel) predict(m::FixedEffectModel, df) residuals(m::FixedEffectModel, df) ``` -Note that the functions `predict` and `residuals` require a table (`df`) as a second argument because the object returned by `reg` does not store the original dataset (to keep the model lightweight). For background on the tradeoff of storing the original data inside fitted model objects, see the following discussions: [1](http://www.r-bloggers.com/trimming-the-fat-from-glm-models-in-r/), [2](https://blogs.oracle.com/R/entry/is_the_size_of_your), [3](http://stackoverflow.com/questions/21896265/how-to-minimize-size-of-object-of-class-lm-without-compromising-it-being-passe), [4](http://stackoverflow.com/questions/15260429/is-there-a-way-to-compress-an-lm-class-for-later-prediction), [here](http://stackoverflow.com/questions/26010742/using-stargazer-with-memory-greedy-glm-objects), and [5](http://stackoverflow.com/questions/22577161/not-enough-ram-to-run-stargazer-the-normal-way). +Note that the functions `predict` and `residuals` require a table (`df`) as a second argument because the object returned by `reg` does not store the original dataset (to keep the model lightweight). For background on the tradeoff of storing the original data inside fitted model objects, see [1](http://www.r-bloggers.com/trimming-the-fat-from-glm-models-in-r/), [2](https://blogs.oracle.com/R/entry/is_the_size_of_your), [3](http://stackoverflow.com/questions/21896265/how-to-minimize-size-of-object-of-class-lm-without-compromising-it-being-passe), [4](http://stackoverflow.com/questions/15260429/is-there-a-way-to-compress-an-lm-class-for-later-prediction), [5](http://stackoverflow.com/questions/26010742/using-stargazer-with-memory-greedy-glm-objects), and [6](http://stackoverflow.com/questions/22577161/not-enough-ram-to-run-stargazer-the-normal-way). -Finally, you may use [RegressionTables.jl](https://github.com/jmboehm/RegressionTables.jl) to get publication-quality regression tables. +Finally, you can use [RegressionTables.jl](https://github.com/jmboehm/RegressionTables.jl) to get publication-quality regression tables. ## Performances From f4ecbdde37d2babef9cb24b06f3521dee90b8def Mon Sep 17 00:00:00 2001 From: Matthieu Gomez Date: Wed, 21 Jan 2026 11:40:23 -0500 Subject: [PATCH 8/8] Revise GPU support section in README Updated GPU usage instructions in README. --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index a9bc2f2..8f63ab6 100755 --- a/README.md +++ b/README.md @@ -126,7 +126,6 @@ Finally, you can use [RegressionTables.jl](https://github.com/jmboehm/Regression The package has an experimental support for GPUs. This can make the package an order of magnitude faster for complicated problems. If you have a Nvidia GPU, run `using CUDA` before `using FixedEffectModels`. Then, estimate a model with `method = :CUDA`. - ```julia using CUDA, FixedEffectModels @assert CUDA.functional()