\value documentation to
confint.panglm(), fitted.panglm(),
summary.panglm(), and vcov.panglm(),
describing the structure and meaning of each return value (CRAN
resubmission).DESCRIPTION
as <doi:...> links.model = "random", family = "gaussian"
always reported logLik/AIC/ BIC
as NA, even though fit_random_gaussian()
already estimates the Swamy-Arora variance components
(sigma_v2, sigma_mu2) needed to compute a real
likelihood - they were simply discarded. Added the closed-form Gaussian
random-intercept log-likelihood (Sherman-Morrison identity on
Omega_i = sigma_v2 * I + sigma_mu2 * J), using the already-
estimated coefficients and variance components. Cross-validated: on the
bundled copd data, logLik(random) closely
tracks logLik(pooling) on the same formula, as expected
since random-effects GLS nests pooled OLS as
sigma_mu2 -> 0.model = "within" (one-way and two-way) had the same
loglik = NA_real_ gap. By the Frisch-Waugh-Lovell theorem
the demeaned-regression residuals are algebraically identical to the
full dummy-variable-regression residuals, so the standard OLS ML
Gaussian log-likelihood applies directly - added, using the
npar (regressors + fixed-effect count + 1 dispersion
parameter) that panglm_parameter_count() already computed
for these branches but previously had no likelihood to pair with.glance.panglm() now reports
r.squared/adj.r.squared (computed from
fitted.values()/y) for every model type;
previously not reported at all.panglm(model = "random", effect = "individual", family = "gaussian")
printed a raw
solve(): system is singular; attempting approx solution
from Armadillo whenever a covariate was time-invariant (e.g. baseline
sex alongside a pre/post indicator) or the panel was balanced with a
deterministic time indicator (e.g. any two-wave pre/post design) - both
make the intermediate within/between regressions used to estimate the
Swamy-Arora variance components exactly rank-deficient. The estimates
were already correct (verified against lme4::lmer), but the
warning bypassed R’s condition system entirely. Switched those two
intermediate regressions to stats::lm.fit(), which handles
rank deficiency via pivoted QR the same way lm() does, with
no near-singular solve and no raw stderr output.CRAN submission candidate. Adds a bundled synthetic dataset,
copd (a simulated COPD follow-up panel), and runnable
@examples to every exported function and documented
method.
plot.panglm() for coefficient, residual, and
fitted-value views, and plot.panglm_hurdle() for the two
hurdle components.panglm_hurdle() through
count_family = "negbin".logLik() now
counts fitted dispersion, shape, variance, and absorbed fixed-effect
parameters where they belong to the reported likelihood. Gaussian pooled
likelihoods use the maximum-likelihood variance while retaining the
unbiased residual variance for covariance estimation.
glance() now reports AIC, BIC, and the likelihood degrees
of freedom.na.exclude restores fitted values and residuals to the
input length, and panel indexes are checked for missing or duplicate
individual-time keys. Nontrivial weights and nonzero offsets now fail
explicitly instead of risking an apparently successful fit that ignores
them.First CRAN submission candidate. Consolidates the estimators,
inference, and zero-inflated-count support added since 0.1.0 (see
below); no functional changes since the last version bump beyond
package-metadata and documentation cleanup for submission
(URL/BugReports fields, vignette
housekeeping).
Initial release.
model = "pooling": gaussian/poisson/binomial GLM via
IRLS, and genuine NB2 (negative binomial) via theta-profiled IRLS –
matches MASS::glm.nb() exactly.
(family = "negbin" previously silently aliased to Poisson
at every model level; this is fixed everywhere below.)model = "within": gaussian (exact demeaning, one-way or
effect = "twoways"), poisson (conditional MLE, one-way or
effect = "twoways" via outer-IRLS/inner-weighted-FWL – the
algorithm behind fixest::feglm()), negative binomial
(Allison & Waterman 2002 unconditional dummy-variable estimator –
matches fixest::fenegbin() exactly; tractable for
small-to-moderate N, not intended for very large panels), and binomial
(exact conditional logistic regression, Chamberlain 1980 – matches
survival::clogit(method = "exact"), no pglm
equivalent). effect = "twoways" is available for gaussian,
poisson, and negbin (the latter two via outer-IRLS/inner-weighted-FWL,
matching fixest::fenegbin() exactly); not yet for binomial
(no general closed-form two-way conditional logit exists).message()) before fitting the Allison-Waterman FE-NB2
estimator – their dummy-variable intercept is unbounded under the log
link, the same boundary case
model = "within", family = "binomial" already screened for.
Previously left in, this could contaminate the shared covariate
coefficients via the joint solve, not just the offending group’s own
intercept.model = "random": gaussian (Swamy-Arora), poisson
(Poisson-Gamma, a single dispersion parameter), negative binomial (a
genuinely different, 2-parameter beta-negative-binomial mixture matching
pglm’s lnl.negbin.R exactly – previously
aliased to the Poisson-Gamma model), and binomial (Gauss-Hermite
quadrature) random effects. The random-effects Poisson fit now seeds
from the pooled-Poisson MLE plus a method-of-moments dispersion
estimate, and uses Levenberg-Marquardt/ridge damping (with a warning
when it engages) instead of erroring on a singular Hessian – verified on
heavily zero-inflated, extremely skewed panels that previously
crashed.vcov(fit, type = "HC1" | "cluster") for pooled/within
models, including effect = "twoways" (gaussian) and within
negbin (Allison-Waterman): the sandwich correction uses the full
covariate+dummy score and bread (all (k+G) parameters), not just the
covariate block, since the dummy intercepts are jointly estimated and
contribute sampling variability of their own. Random-effects models
intentionally keep model-based (information-matrix) SEs only, matching
lme4/glmmTMB convention.confint.panglm() – Wald intervals using whichever vcov
the fit currently carries.panglm_dispersiontest() – Pearson chi-squared/df
overdispersion test for poisson/negbin fits with available
fitted.values. Observations with a zero or unavailable
fitted value (e.g. rows in an all-zero group screened out of a
fixed-effects negbin fit) are excluded from the statistic rather than
producing a 0/0 = NaN; the excluded count is
reported as n_excluded on the returned object.panglm_hausman() for FE-vs-RE specification
testing.tidy()/glance() methods registered against
generics::tidy/glance for
broom/modelsummary compatibility.panglm_hurdle(): a fixed-effects hurdle model for
panels with structural zeros (a pattern that shows up as extreme,
family-invariant overdispersion under either
family = "poisson" or family = "negbin" in
panglm()). Fits 1(y>0) via the existing
conditional-logit FE estimator, and a zero-truncated Poisson or NB2 FE
model (an Allison-Waterman-style dummy-variable estimator,
Newton-Raphson with exact Fisher information) on the y>0
subsample. The truncated-Poisson math (no fixed effects) matches
pscl::hurdle()’s count part exactly. Both zero-truncated
likelihoods are validated against pscl::hurdle().effect = "twoways" not yet available for binomial (no
general closed-form two-way conditional logit exists).