--- title: "A Comprehensive Guide to Fractional Response Regressions with fracreg" author: "Sulman Olieko Owili" date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{A Comprehensive Guide to Fractional Response Regressions with fracreg} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include=FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", eval = TRUE ) local({ hook_output <- knitr::knit_hooks$get("output") knitr::knit_hooks$set(output = function(x, options) { paste0("\n
Toggle to see the output\n\n", hook_output(x, options), "\n
\n") }) }) library(fracreg) ``` ## Introduction The **`fracreg`** package is the most comprehensive tool available in R for estimating, diagnosing, and interpreting fractional response models. Originally focused on standard cross-sectional models, it has been substantially expanded to provide a complete suite of fractional response methodologies. The package supports: - **Cross-Sectional Models (`fracreg`)**: Includes one-part models (1P) for standard $[0, 1]$ fractions, two-part hurdle models (2P) for fractions with boundaries at 0 or 1, and three-part double-inflated models (3P) for inflation at both boundaries. - **Panel Data Models (`fracregpd`)**: Utilises Correlated Random Effects (CRE), Quasi-Maximum Likelihood (QML), and Generalised Method of Moments (GMM) approaches for longitudinal data. - **Endogeneity Correction (`fracreghet`)**: Corrects for endogenous covariates using Control Function and IV-GMM approaches. - **Fractional Multinomial Logit (`fracregmlogit`)**: Models multivariate fractional outcomes where multiple fractions sum to 1. - **Fractional Ridge Regression (`fracregridge`)**: Incorporates L2 regularization dynamically controlled by the fraction of the unregularized coefficient vector length. This vignette walks you through comprehensive empirical examples (using the built-in 401(k) and spending datasets) and simulated examples for each estimator. We provide detailed explanations of why each model is used and how to interpret the associated outputs. ```{r load-package} library(fracreg) ``` ## 1. Data Description and Preparation We use the built-in `fracreg_k401k` dataset to demonstrate univariate fractional models. This is the canonical firm-level 401(k) plan participation data used in **Papke and Wooldridge (1996)** (*"Econometric methods for fractional response variables with an application to 401(k) plan participation rates"*, Journal of Applied Econometrics). The dataset contains 1,534 observations of 401(k) plans. The primary variables we use are: - `prate`: The plan participation rate (the fraction of eligible employees who are active participants). It strictly falls in the $[0, 1]$ interval and serves as our dependent variable ($y$). - `mrate`: The firm's matching rate (the firm's contribution per $1 of employee contribution). - `age`: The age of the 401(k) plan. - `totemp`: Total number of employees at the firm. - `sole`: A binary indicator equal to 1 if the 401(k) plan is the sole retirement plan offered by the firm. --- ## 2. Cross-Sectional Fractional Models (`fracreg`) The core `fracreg()` function is designed for univariate models where the dependent variable is bounded between 0 and 1 inclusive ($0 \le y \le 1$). We explore how to fit 1P, 2P, and 3P models using both the empirical 401(k) data and simulated data with strict boundaries. ### 2.1 Empirical and Simulated Fractional Regressions In this section, we start with a standard 1-part (1P) fractional logit model to estimate participation rates in the 401(k) data. Since we might also be interested in multiplicative effects, we show how to extract odds ratios (`or=TRUE`). Next, we demonstrate how to tackle boundary inflation. For example, some firms might have 100% participation (`prate = 1`), so we fit a 2-part model (`inflation=1`). The simulated section further demonstrates generating artificial inflation at exactly 0 and 1. We then isolate the components of the 2-part model (using `type="2Pbin"` and `type="2Pfrac"`) and fit full 3-part models. ```{r fracreg} ### Empirical 401(k) Examples data("fracreg_k401k") y <- fracreg_k401k$prate X <- cbind(mrate = fracreg_k401k$mrate, age = fracreg_k401k$age, totemp = fracreg_k401k$totemp, sole = fracreg_k401k$sole) # 1P Model mod <- fracreg(y, X, type="1P", linkfrac="logit") summary(mod) # 1P Model reporting odds ratios and 99% confidence intervals mod <- fracreg(y, X, type="1P", linkfrac="logit", or=TRUE, level=0.99) summary(mod) # 2P Model (modelling mass at 1) mod <- fracreg(y, X, type="2P", inflation=1, linkbin="logit", linkfrac="logit") summary(mod) # 3P Model (inject artificial 0s for demonstration) y_3p <- y; y_3p[1:50] <- 0 mod <- fracreg(y_3p, X, type="3P", linkbin=c("logit","logit"), linkfrac="logit") summary(mod) ### Simulated Examples set.seed(123) N <- 1000 x1 <- rnorm(N) x2 <- runif(N) # Generating a fractional dependent variable with inflation at 0 and 1 XB <- -0.5 + 0.8 * x1 + 1.2 * x2 + rnorm(N) y_latent <- exp(XB) / (1 + exp(XB)) y <- y_latent # Inflate at boundaries y[y_latent < 0.2] <- 0 y[y_latent > 0.8] <- 1 X <- cbind(x1 = x1, x2 = x2) # fracreg estimation of a logit fractional response model mod <- fracreg(y, X, type="1P", linkfrac="logit") summary(mod) ``` #### 2.1.2 Binary Logit Component of a Two-Part Model Here, we estimate the binary (hurdle) component of a two-part fractional regression model. We specify `type="2Pbin"`, which instructs the function to model the probability of observing a non-boundary value versus the boundary value (in this case, 0). The `inflation=0` argument explicitly sets 0 as the relevant boundary. ```{r fracreg_2pbin} # Estimate the binary logit component mod <- fracreg(y, X, type="2Pbin", inflation=0, linkbin="logit") summary(mod) ``` #### 2.1.3 Fractional Component of a Two-Part Model After modelling the hurdle, we estimate the continuous fractional component using `type="2Pfrac"`. This component only uses observations that are strictly bounded away from the inflated boundary ($y > 0$). In this example, we apply a **probit** link function to model the fractional values. ```{r fracreg_2pfrac} # Estimate the fractional component using a probit link mod <- fracreg(y, X, type="2Pfrac", inflation=0, linkfrac="probit") summary(mod) ``` #### 2.1.4 Full Two-Part Model (Joint Estimation) Alternatively, we can estimate both the binary and fractional components simultaneously by specifying `type="2P"`. Here we use different link functions for each part: a **cloglog** link for the binary hurdle (which is useful for asymmetric data) and a **logit** link for the fractional continuous part. ```{r fracreg_2p_joint} # Estimate both components jointly mod <- fracreg(y, X, type="2P", inflation=0, linkbin="cloglog", linkfrac="logit") summary(mod) ``` #### 2.1.5 Three-Part Double-Inflated Model When the data exhibits inflation at **both** 0 and 1, a three-part model (`type="3P"`) is required. This models the probability of observing 0, the probability of observing 1, and the continuous fractional outcomes in between. We pass a vector of link functions `c("logit", "probit")` for the binary components, alongside the `logit` fractional link. ```{r fracreg_3p_simulated} # Three-part double-inflated model mod <- fracreg(y, X, type="3P", linkbin=c("logit","probit"), linkfrac="logit") summary(mod) ``` ### 2.2 Partial Effects (`fracreg.pe`) Because fractional models are inherently non-linear, raw coefficients cannot be interpreted directly as constant marginal effects. The `fracreg.pe()` function computes the actual marginal effects. We can compute Average Partial Effects (APE) across all observations or Conditional Partial Effects (CPE) evaluated at specific covariate values (e.g., holding covariates at their median). The examples below demonstrate how to extract these effects across standard, 2-part, and 3-part models. ```{r fracreg-pe} ### Empirical 401(k) Examples data("fracreg_k401k") y <- fracreg_k401k$prate X <- cbind(mrate = fracreg_k401k$mrate, age = fracreg_k401k$age, totemp = fracreg_k401k$totemp, sole = fracreg_k401k$sole) m <- fracreg(y, X, type="1P", linkfrac="logit") pe_res <- fracreg.pe(m) summary(pe_res) ### Simulated Examples N <- 250 u <- rnorm(N) X <- cbind(rnorm(N),rnorm(N)) dimnames(X)[[2]] <- c("X1","X2") ym <- exp(X[,1]+X[,2]+u)/(1+exp(X[,1]+X[,2]+u)) y <- rbeta(N,ym*20,20*(1-ym)) y[y > 0.9] <- 1 #Computing average partial effects for a logit fractional response model mod <- fracreg(y,X,linkfrac="logit",table=FALSE) pe_res <- fracreg.pe(mod) summary(pe_res) ``` #### 2.2.2 APEs for a Two-Part Model When the data has boundary inflation (e.g., at 1), partial effects must account for both the hurdle process and the fractional continuous process. The `fracreg.pe()` function automatically handles this composite calculation for `type="2P"`. ```{r fracreg_pe_2p} # Compute average partial effects for a binary logit + fractional probit two-part model mod <- fracreg(y,X,linkbin="logit",linkfrac="probit",type="2P",inf=1,table=FALSE) pe_res <- fracreg.pe(mod) summary(pe_res) ``` #### 2.2.3 Conditional Partial Effects (CPE) Instead of averaging the effects over all observations (APE), you may want the effect for a "typical" observation. By setting `APE=FALSE` and `CPE=TRUE`, and providing `at="median"`, we compute the Conditional Partial Effect evaluated at the median values of all covariates. We isolate the effect of `X2` using `which.x="X2"`. ```{r fracreg_pe_cpe} # Compute conditional partial effects for X2 at median values mod <- fracreg(y,X,linkfrac="logit",type="2Pfrac",inf=1,table=FALSE) pe_res <- fracreg.pe(mod,APE=FALSE,CPE=TRUE,at="median",which.x="X2") summary(pe_res) ``` #### 2.2.4 APEs for a Three-Part Model For double-inflated models (`type="3P"`), the partial effect calculation incorporates both boundary probabilities and the interior fractional distribution. ```{r fracreg_pe_3p} # Compute average partial effects for a three-part double-inflated model y3p <- y y3p[1:20] <- 0 y3p[21:40] <- 1 res3p <- fracreg(y3p,X,linkbin=c("logit","probit"),linkfrac="logit",type="3P",table=FALSE) pe_res <- fracreg.pe(res3p) summary(pe_res) ``` --- ## 3. Hypothesis Testing and Specification Diagnostics `fracreg` includes state-of-the-art specification tests to validate your model's functional form and link function assumptions. ### 3.1 Generalised Goodness-Of-Functional-Form (`fracreg.ggoff`) The GGOFF test checks if the chosen link function (e.g., `logit`, `probit`) is appropriate for the data. A significant test statistic suggests that the link function may be misspecified and an alternative should be explored. Here, we run the LM, Wald, and LR variations of the test on our fitted fractional models. ```{r fracreg-ggoff} ### Empirical 401(k) Examples data("fracreg_k401k") y <- fracreg_k401k$prate X <- cbind(mrate = fracreg_k401k$mrate, age = fracreg_k401k$age, totemp = fracreg_k401k$totemp, sole = fracreg_k401k$sole) m <- fracreg(y, X, type="1P", linkfrac="logit") ggoff_res <- fracreg.ggoff(m) summary(ggoff_res) ### Simulated Examples N <- 250 u <- rnorm(N) X <- cbind(rnorm(N),rnorm(N)) dimnames(X)[[2]] <- c("X1","X2") ym <- exp(X[,1]+X[,2]+u)/(1+exp(X[,1]+X[,2]+u)) y <- rbeta(N,ym*20,20*(1-ym)) y[y > 0.9] <- 1 #Testing the logit specification of a standard fractional response model #using LM and Wald versions of the GGOFF test, based on 1 or 2 fitted powers of #the linear predictor mod <- fracreg(y,X,linkfrac="logit",table=FALSE) ggoff_res <- fracreg.ggoff(mod,c("Wald","LM")) summary(ggoff_res) ``` #### 3.1.2 GGOFF Test for the Binary Component The GGOFF test can also be applied to individual components of hurdle models. Here, we test the **probit** specification of the binary component (`2Pbin`) using a Likelihood Ratio (LR) test approach. ```{r fracreg_ggoff_2pbin} # Test the probit specification of the binary component mod <- fracreg(y,X,linkbin="probit",type="2Pbin",inf=1,table=FALSE) ggoff_res <- fracreg.ggoff(mod,"LR") summary(ggoff_res) ``` ### 3.2 RESET Test (`fracreg.reset`) The RESET test detects general functional form misspecification by testing whether powers of the fitted values have explanatory power. Testing $H_0: \gamma = 0$ provides a robust diagnostic check against omitted non-linearities. ```{r fracreg-reset} ### Empirical 401(k) Examples data("fracreg_k401k") y <- fracreg_k401k$prate X <- cbind(mrate = fracreg_k401k$mrate, age = fracreg_k401k$age, totemp = fracreg_k401k$totemp, sole = fracreg_k401k$sole) m <- fracreg(y, X, type="1P", linkfrac="logit") reset_res <- fracreg.reset(m) summary(reset_res) ### Simulated Examples N <- 250 u <- rnorm(N) X <- cbind(rnorm(N),rnorm(N)) dimnames(X)[[2]] <- c("X1","X2") ym <- exp(X[,1]+X[,2]+u)/(1+exp(X[,1]+X[,2]+u)) y <- rbeta(N,ym*20,20*(1-ym)) y[y > 0.9] <- 1 #Testing the logit specification of a standard fractional response model #using LM and Wald versions of the RESET test, based on 1 or 2 fitted powers of #the linear predictor mod <- fracreg(y,X,linkfrac="logit",table=FALSE) reset_res <- fracreg.reset(mod,2:3,c("Wald","LM")) summary(reset_res) ``` #### 3.2.2 RESET Test for the Binary Component Similar to GGOFF, the RESET test can validate individual hurdle components. Here, we use the Likelihood Ratio (LR) version of the RESET test on the binary probit component, checking up to cubic fitted powers of the linear predictor. ```{r fracreg_reset_2pbin} # Test the probit specification of the binary component using LR RESET mod <- fracreg(y,X,linkbin="probit",type="2Pbin",inf=1,table=FALSE) reset_res <- fracreg.reset(mod,3,"LR") summary(reset_res) ``` ### 3.3 P-Test for Non-Nested Models (`fracreg.ptest`) When you need to choose between two non-nested model specifications (for example, a `logit` link vs. a `probit` or `loglog` link, or a 1P vs. a 2P model), the P-test compares them directly to see if one statistically dominates the other. ```{r fracreg-ptest} ### Empirical 401(k) Examples data("fracreg_k401k") y <- fracreg_k401k$prate X <- cbind(mrate = fracreg_k401k$mrate, age = fracreg_k401k$age, totemp = fracreg_k401k$totemp, sole = fracreg_k401k$sole) m1 <- fracreg(y, X, type="1P", linkfrac="logit") m2 <- fracreg(y, X, type="1P", linkfrac="probit") ptest_res <- fracreg.ptest(m1, m2) summary(ptest_res) ### Simulated Examples N <- 250 u <- rnorm(N) X <- cbind(rnorm(N),rnorm(N)) dimnames(X)[[2]] <- c("X1","X2") ym <- exp(X[,1]+X[,2]+u)/(1+exp(X[,1]+X[,2]+u)) y <- rbeta(N,ym*20,20*(1-ym)) y[y > 0.9] <- 1 #Testing logit versus loglog specifications for standard fractional #regression models using a LM version of the P test res1 <- fracreg(y,X,linkfrac="logit",table=FALSE) res2 <- fracreg(y,X,linkfrac="loglog",table=FALSE) ptest_res <- fracreg.ptest(res1,res2,"LM") summary(ptest_res) ``` #### 3.3.2 P-Test: 1P vs. 2P Model The P-test is exceptionally useful for deciding whether a simple 1-part model suffices, or if the extra complexity of a 2-part model is statistically justified. We test the `1P` logit model against a `2P` (binary logit + fractional probit) model using the Wald test statistic. ```{r fracreg_ptest_1p_vs_2p} # Test 1P logit versus 2P logit-probit using Wald P-test res1 <- fracreg(y,X,linkfrac="logit",table=FALSE) res2 <- fracreg(y,X,linkbin="logit",linkfrac="probit",type="2P",inf=1,table=FALSE) ptest_res <- fracreg.ptest(res1,res2,"Wald") summary(ptest_res) ``` --- ## 4. Endogeneity & Heteroscedasticity (`fracreghet`) When a covariate is endogenous (correlated with the error term) or heteroscedasticity is present, standard maximum likelihood estimation becomes inconsistent. `fracreghet()` provides Instrumental Variable (IV) corrections using Control Function (CF) and Generalised Method of Moments (GMM) approaches. In the empirical example below, we suspect `mrate` (matching rate) might be endogenous. We use `age` and `ltotemp` (log of total employees) as instruments. We estimate the model using a Quasi-Maximum Likelihood control function approach (`QMLxv`). We also show how to extract odds ratios. In the simulated examples, we explore `GMMx`, `GMMz`, and `GMMxv` estimators which relax the need for a linear first-stage relationship in different ways. ```{r fracreghet} ### Empirical 401(k) Examples data("fracreg_k401k") y <- fracreg_k401k$prate X_het <- cbind(mrate = fracreg_k401k$mrate, ltotemp = fracreg_k401k$ltotemp) # fracreghet estimators do not allow exact 1s or 0s y_adj <- y y_adj[y_adj == 1] <- 0.999 # Instrument mrate using age Z_emp <- cbind(age = fracreg_k401k$age, ltotemp = fracreg_k401k$ltotemp) mod <- fracreghet(y_adj, X_het, Z_emp, var.endog = X_het[, "mrate"], type="QMLxv", link="logit") summary(mod) # Compute the same QMLxv estimator reporting Odds Ratios with 90% confidence intervals mod <- fracreghet(y_adj, X_het, Z_emp, var.endog = X_het[, "mrate"], type="QMLxv", link="logit", or=TRUE, level=0.90) summary(mod) ### Simulated Examples set.seed(123) N <- 1000 x1 <- rnorm(N) # Simulating an endogenous variable (var.endog) and an instrument (z1) z1 <- rnorm(N) u <- 0.5 * z1 + rnorm(N) var.endog <- 0.8 * z1 + u y_endog <- exp(0.5 * x1 + 1.2 * var.endog + u) / (1 + exp(0.5 * x1 + 1.2 * var.endog + u)) # Avoid exact 0 or 1 boundaries for some estimators y_endog[y_endog <= 0] <- 0.01 y_endog[y_endog >= 1] <- 0.99 X <- cbind(x1 = x1, var.endog = var.endog) Z <- cbind(x1 = x1, z1 = z1) # Exogeneity (assuming var.endog is exogenous for comparison), GMMx estimator mod <- fracreghet(y = y_endog, x = X, type = "GMMx", link = "logit") summary(mod) ``` #### 4.1.2 GMMz Estimator The **GMMz** estimator handles endogeneity directly through moment conditions using the instruments $Z$, without requiring an explicit linear reduced form equation for the endogenous variable. This approach is more robust to first-stage misspecification. ```{r fracreghet_gmmz} # Endogeneity, GMMz estimator mod <- fracreghet(y = y_endog, x = X, z = Z, type = "GMMz", link = "logit") summary(mod) ``` #### 4.1.3 GMMxv Estimator The **GMMxv** estimator is a variation that does assume a linear reduced form for the endogenous variable, utilizing the first-stage residuals within the generalized method of moments framework to correct for endogeneity. ```{r fracreghet_gmmxv} # Endogeneity, GMMxv estimator mod <- fracreghet(y = y_endog, x = X, z = Z, var.endog = var.endog, type = "GMMxv", link = "logit") summary(mod) ``` #### 4.1.4 QMLxv Control Function Estimator The **QMLxv** approach utilizes a Control Function (CF). It explicitly estimates the first-stage linear reduced form, extracts the residuals, and includes them as control variables in the second-stage Quasi-Maximum Likelihood estimation to absorb the endogeneity. ```{r fracreghet_qmlxv} # Endogeneity, QMLxv control function approach mod <- fracreghet(y = y_endog, x = X, z = Z, var.endog = var.endog, type = "QMLxv", link = "logit") summary(mod) ``` ### 4.1 Partial Effects for Endogenous Models (`fracreghet.pe`) Partial effects can also be calculated for endogenous models. When using a control function approach (`QMLxv`), `fracreghet.pe` accurately integrates over the estimated first-stage residuals, offering a corrected smearing estimation. ```{r fracreghet-pe} ### Empirical 401(k) Examples data("fracreg_k401k") y <- fracreg_k401k$prate X_het <- cbind(mrate = fracreg_k401k$mrate, ltotemp = fracreg_k401k$ltotemp) # fracreghet estimators do not allow exact 1s or 0s y_adj <- y y_adj[y_adj == 1] <- 0.999 # Instrument mrate using age Z_emp <- cbind(age = fracreg_k401k$age, ltotemp = fracreg_k401k$ltotemp) res_emp <- fracreghet(y_adj, X_het, Z_emp, var.endog = X_het[, "mrate"], type="QMLxv", link="logit", table=FALSE) pe_res <- fracreghet.pe(res_emp, which.x="mrate") summary(pe_res) ### Simulated Examples N <- 250 u <- rnorm(N) X <- cbind(rnorm(N),rnorm(N)) dimnames(X)[[2]] <- c("X1","X2") Z <- cbind(rnorm(N),rnorm(N),rnorm(N)) dimnames(Z)[[2]] <- c("Z1","Z2","Z3") y <- exp(X[,1]+X[,2]+u)/(1+exp(X[,1]+X[,2]+u)) mod <- fracreghet(y,X,type="GMMx",table=FALSE) #Smearing estimator of average partial effects for variable X1 pe_res <- fracreghet.pe(mod,which.x="X1") summary(pe_res) ``` #### 4.1.2 Naive Estimator for CPEs For a targeted interpretation, we can calculate Conditional Partial Effects (CPE) evaluated at specific fixed values (e.g., $X1=1$ and $X2=-1$). By setting `smearing=FALSE`, we use a naive estimator that does not integrate over the estimated unobserved heterogeneity. ```{r fracreghet_pe_cpe} # Naive estimator of CPE evaluated at fixed values pe_res <- fracreghet.pe(mod,smearing=FALSE,APE=FALSE,CPE=TRUE,at=c(1,-1)) summary(pe_res) ``` ### 4.2 RESET Test for Endogenous Models (`fracreghet.reset`) Just as with `fracreg`, we can run RESET specification tests on our heteroscedasticity and endogeneity-robust models to assure proper functional form. ```{r fracreghet-reset} ### Empirical 401(k) Examples data("fracreg_k401k") y <- fracreg_k401k$prate X_het <- cbind(mrate = fracreg_k401k$mrate, ltotemp = fracreg_k401k$ltotemp) # fracreghet estimators do not allow exact 1s or 0s y_adj <- y y_adj[y_adj == 1] <- 0.999 # Instrument mrate using age Z_emp <- cbind(age = fracreg_k401k$age, ltotemp = fracreg_k401k$ltotemp) res_emp <- fracreghet(y_adj, X_het, type="GMMx", link="logit", table=FALSE) reset_res <- fracreghet.reset(res_emp) summary(reset_res) ### Simulated Examples N <- 250 u <- rnorm(N) X <- cbind(rnorm(N),rnorm(N)) dimnames(X)[[2]] <- c("X1","X2") Z <- cbind(rnorm(N),rnorm(N),rnorm(N)) dimnames(Z)[[2]] <- c("Z1","Z2","Z3") y <- exp(X[,1]+X[,2]+u)/(1+exp(X[,1]+X[,2]+u)) mod <- fracreghet(y,X,type="GMMx",table=FALSE) #LM and Wald versions of the RESET test, based on 1 or 2 fitted powers of xb reset_res <- fracreghet.reset(mod,2:3,c("Wald","LM")) summary(reset_res) ``` --- ## 5. Panel Data Fractional Models (`fracregpd`) When you observe the same entities over multiple time periods, unobserved individual heterogeneity must be accounted for. `fracregpd()` provides fixed-T panel estimators. We explore Correlated Random Effects (CRE) which includes time-averages of the covariates to proxy the unobserved effect, as well as various panel GMM estimators (like `GMMbgw`, `GMMww`, and `GMMpfe`) which can handle lagged dependent variables, endogenous covariates, and time dummies. ```{r fracregpd} ### Empirical 401(k) Examples data("fracreg_k401k") y <- fracreg_k401k$prate X <- cbind(mrate = fracreg_k401k$mrate, age = fracreg_k401k$age, totemp = fracreg_k401k$totemp, sole = fracreg_k401k$sole) # Artificial panel data structure for demonstration N_emp <- nrow(X) id_emp <- rep(1:(N_emp/2), each=2) time_emp <- rep(1:2, times=N_emp/2) mod <- fracregpd(id_emp, time_emp, y, X, type="QMLcre", link="probit") summary(mod) ### Simulated Examples set.seed(123) # Simulating Panel Data N <- 100 T_periods <- 5 id <- rep(1:N, each = T_periods) time <- rep(1:T_periods, times = N) x_panel <- rnorm(N * T_periods) # Unobserved individual effect (CRE) c_i <- rep(rnorm(N), each = T_periods) y_panel <- exp(x_panel + c_i) / (1 + exp(x_panel + c_i)) X <- cbind(x_panel = x_panel) # Endogenous variable and instrument simulation z_panel <- rnorm(N * T_periods) u_panel <- 0.5 * z_panel + rnorm(N * T_periods) var_endog <- 0.8 * z_panel + u_panel y_endog <- exp(x_panel + 1.2 * var_endog + c_i + u_panel) / (1 + exp(x_panel + 1.2 * var_endog + c_i + u_panel)) X_endog <- cbind(x_panel = x_panel, var_endog = var_endog) Z_inst <- cbind(x_panel = x_panel, z_panel = z_panel) # Estimate a Correlated Random Effects (CRE) Model mod <- fracregpd(id=id, time=time, y=y_panel, x=X, type="QMLcre", link="probit") summary(mod) ``` #### 5.1.2 Standard Panel GMM (GMMbgw) The **GMMbgw** estimator is a standard GMM panel approach that doesn't explicitly model unobserved effects via time-averages, but relies on moment conditions. Here we apply it with clustered standard errors. ```{r fracregpd_gmmbgw} # Exogeneity, GMMbgw estimator mod <- fracregpd(id=id, time=time, y=y_panel, x=X, type="GMMbgw") summary(mod) ``` #### 5.1.3 Generalized Method of Moments (GMMww) The **GMMww** estimator extends panel GMM capabilities. Below, we estimate the model and demonstrate how to extract odds ratios (`or=TRUE`) with a 99% confidence level. ```{r fracregpd_gmmww} # Estimate GMMww estimator with odds ratios mod <- fracregpd(id=id, time=time, y=y_panel, x=X, type="GMMww", or=TRUE, level=0.99) summary(mod) ``` #### 5.1.4 GMMww with Lagged Covariates Dynamic panel data often require the inclusion of lagged covariates as instruments. By setting `lags=TRUE`, the model automatically configures the moment conditions using lagged values, employing robust standard errors to handle potential heteroscedasticity across time periods. ```{r fracregpd_gmmww_lags} # Lagged covariates and instruments mod <- fracregpd(id=id, time=time, y=y_panel, x=X, lags=TRUE, type="GMMww", var.type="robust") summary(mod) ``` #### 5.1.5 Endogenous Panel GMM (GMMpfe) When covariates are endogenous in a panel setting, we combine instruments ($Z$) with panel structure. The **GMMpfe** estimator allows for endogenous variables (`x.exogenous=FALSE`) and includes time dummies (`tdummies=TRUE`) to control for macroeconomic or aggregate time shocks. ```{r fracregpd_gmmpfe} # Endogeneity, time dummies, GMMpfe estimator mod <- fracregpd(id=id, time=time, y=y_endog, x=X_endog, z=Z_inst, x.exogenous=FALSE, type="GMMpfe", tdummies=TRUE) summary(mod) ``` --- ## 6. Fractional Ridge Regression The `fracreg` package also includes an implementation of Fractional Ridge Regression (`fracregridge`). Standard maximum likelihood approaches can suffer from multicollinearity or overfitting when the number of covariates is large relative to the sample size. `fracregridge` implements Fractional Ridge Regression, which applies L2 regularization to shrink coefficients. Unlike standard ridge regression where the penalty term $\alpha$ is chosen directly, `fracregridge` allows you to specify the desired *fraction* of the unregularized OLS coefficient vector length (e.g. `0.2` implies shrinking to 20% of the full OLS length). The algorithm then automatically determines the corresponding $\alpha$ penalties. ### 6.1 Empirical 401(k) Example We can apply this to the 401(k) participation rate data to observe how the coefficients dynamically shrink across different target vector length fractions (from 20% to 100%). We also demonstrate how to compute partial effects on the regularized coefficients. ```{r fracregridge-empirical} data("fracreg_k401k") y_401k <- fracreg_k401k$prate X_401k <- cbind(mrate = fracreg_k401k$mrate, age = fracreg_k401k$age, totemp = fracreg_k401k$totemp, sole = fracreg_k401k$sole) # Fit fractional ridge regression mod_401k <- fracregridge(y = y_401k, x = X_401k, fracs = seq(0.2, 1.0, by = 0.2)) # View full detailed summary showing the chosen alphas summary(mod_401k) # Compute Average Partial Effects for Ridge pe_401k <- fracregridge.pe(mod_401k) summary(pe_401k) ``` ### 6.2 Simulated Data Example Using a random matrix of 10 predictors on 100 observations, we can see how the fraction parameters precisely constrain the output coefficients to 30%, 50%, and 80% lengths. ```{r fracregridge-simulated} # Generate random data set.seed(123) n <- 100 p <- 10 y_sim <- rnorm(n) X_sim <- matrix(rnorm(n * p), n, p) colnames(X_sim) <- paste0("X", 1:p) # Fit Fractional Ridge Regression for 30%, 50%, and 80% fractions mod_sim <- fracregridge(y = y_sim, x = X_sim, fracs = c(0.3, 0.5, 0.8)) # View brief summary print(mod_sim) # Compute Partial Effects pe_sim <- fracregridge.pe(mod_sim) summary(pe_sim) ``` --- ## 7. Fractional Multinomial Logit The `fracreg` package incorporates the fractional multinomial logit (`fracregmlogit`) to estimate fractional response data where the response variable consists of fractions that sum up to one across multiple categories (e.g., budget allocations across departments). A univariate model is insufficient because the bounded choices are perfectly collinear in sum. ### 7.1 Estimating Budget Shares We use the built-in `fracreg_spending` dataset, which records the budget share allocations of local governments across 6 distinct sectors. The sum of these 6 sectoral fractions for any given government is exactly 1. We compute both the model summary and the discrete partial effects for specific explanatory variables. ```{r fracregmlogit_example} # Load the empirical spending data data("fracreg_spending") # Define covariates and fractional responses X <- fracreg_spending[, c("houseval", "popdens", "noleft", "minorityleft", "tot")] y <- fracreg_spending[, c("governing", "safety", "education", "recreation", "social", "urbanplanning")] # Fit the Fractional Multinomial Logit model mn_fit <- fracregmlogit(y, X) # View estimates summary(mn_fit) # Compute Average Partial Effects (discrete) mn_pe <- fracregmlogit.pe(mn_fit, effect = "discrete", varlist = c("noleft", "minorityleft")) summary(mn_pe) ``` ### 7.2 Willingness to Pay (WTP) In policy or consumer choice applications, you might want to calculate the aggregate effect of a variable scaled by arbitrary outcome weights (such as cost, budget, or willingness to pay associated with each choice). The `wtp()` function multiplies the average partial effects by these arbitrary values and tests if the aggregate effect differs from zero. We define a vector of length 6 (to match the 6 categories) and plot the effect. ```{r fracregmlogit_wtp} # Calculate Willingness to Pay for the 'noleft' variable using a hypothetical WTP vector # Assuming WTP = 1, 2, 3, 4, 5, 6 for each of the 6 choices wtp_est <- wtp(mn_pe, wtp.vec = 1:6, varlist = "noleft") summary(wtp_est) # Plot the Willingness to Pay effect across observations plot(mn_fit, wtp.vec = 1:6, varlist = "noleft") ``` ## Conclusion With `fracreg`, `fracreghet`, `fracregpd`, `fracregmlogit`, and `fracregridge`, you have a complete toolkit for modelling fractional responses bounded between $[0,1]$, regardless of inflation, endogeneity, unobserved panel effects, multinomial structure, or multicollinearity. ## Acknowledgements This package builds upon, consolidates, and modernises the fractional regression frameworks originally implemented in the `frm`, `frmhet`, and `frmpd` R packages developed by Joaquim J.S. Ramalho. As those original packages have been deprecated and removed from the active CRAN repository, `fracreg` serves as an actively maintained successor, ensuring these econometric tools remain available to the R community. Furthermore, we acknowledge James Ji (@f1kidd) and A. John Woodill (@johnwoodill), the authors of the `fmlogit` R package on GitHub, whose foundational work on fractional multinomial logit models inspired the implementation of `fracregmlogit`. We also extend our gratitude to Ariel Rokem and Kendrick Kay, the authors of the `fracridge` package, whose methodological contributions to fractional ridge regression are incorporated into the `fracregridge` functionalities of this package. ## References - **Ji, J., and Woodill, A. J.** *fmlogit: Fractional Multinomial Logit*. R package repository. - **Rokem, A., and Kay, K.** *fracridge: Fractional Ridge Regression*. Package repository. - **Ramalho, J. J. S. (2022).** *frm: Fractional Regression Models*. R package. Formerly available on CRAN, currently archived. - **Ramalho, J. J. S. (2023).** *frmhet: Fractional Regression Models under Heterogeneity*. R package. Formerly available on CRAN, currently archived. - **Ramalho, J. J. S. (2023).** *frmpd: Fractional Regression Models for Panel Data*. R package. Formerly available on CRAN, currently archived. - **Buis, M. L. (2008).** "fmlogit: Stata module fitting a fractional multinomial logit model by quasi maximum likelihood", *Statistical Software Components*, Boston College Department of Economics. - **Davidson, R. and MacKinnon, J.G. (1981).** "Several tests for model specification in the presence of alternative hypotheses", *Econometrica*, 49(3), 781-793. - **Fang, K., & Ma, S. (2013).** "Three-part model for fractional response variables with application to Chinese household health insurance coverage", *Journal of Applied Statistics*, 40(5), 925-940. - **Mullahy, J. (2015).** "Multivariate fractional regression estimation of econometric share models", *Journal of Econometric Methods*, 4(1), 71-100. - **Murteira, J. M. R., and Ramalho, J. J. S. (2016).** "Regression analysis of multivariate fractional data", *Econometric Reviews*, 35(4), 515-552. - **Papke, L. E. and Wooldridge, J. M. (1996).** "Econometric methods for fractional response variables with an application to 401(k) plan participation rates", *Journal of Applied Econometrics*, 11(6), 619-632. - **Papke, L. and Wooldridge, J.M. (2008).** "Panel data methods for fractional response variables with an application to test pass rates", *Journal of Econometrics*, 145(1-2), 121-233. - **Pregibon, D. (1980).** "Goodness of Link Tests for Generalized Linear Models", *Journal of the Royal Statistical Society: Series C (Applied Statistics)*, 29(1), 15-24. - **Ramalho, E. A., & Ramalho, J. J. S. (2017).** "Moment-based estimation of nonlinear regression models with boundary outcomes and endogeneity, with applications to nonnegative and fractional responses", *Econometric Reviews*, 36(4), 397-420. - **Ramalho, E.A., Ramalho, J.J.S. and Murteira, J.M.R. (2011).** "Alternative estimating and testing empirical strategies for fractional response models", *Journal of Economic Surveys*, 25(1), 19-68. - **Ramalho, E.A., Ramalho, J.J.S. and Murteira, J.M.R. (2014).** "A generalized goodness-of-functional form test for binary and fractional response models", *Manchester School*, 82(4), 488-507. - **Ramsey, J.B. (1969).** "Tests for Specification Errors in Classical Linear Least-Squares Regression Analysis", *Journal of the Royal Statistical Society: Series B (Methodological)*, 31(2), 350-371. - **Rokem, A., and Kay, K. (2020).** "Fractional ridge regression: a fast, interpretable reparameterization of ridge regression", *GigaScience*, 9(12), giaa133. For more information, please visit the [package website](https://sulmanolieko.github.io/fracreg/) or file an issue on [GitHub](https://github.com/SulmanOlieko/fracreg/issues). To cite this package in your research: ```r citation("fracreg") ```