| Title: | Analysis of Metafrontier Models for Efficiency and Productivity |
|---|---|
| Description: | Implements metafrontier production function models for estimating technical efficiencies and technology gaps for groups of firms that face different restrictions of a common underlying metatechnology (group-specific technologies in the sense of Battese, Rao, and O'Donnell, 2004). Supports both stochastic frontier analysis (SFA) and data envelopment analysis (DEA) based metafrontiers. Includes the deterministic metafrontier of Battese, Rao, and O'Donnell (2004) <doi:10.1023/B:PROD.0000012454.06094.29>, the stochastic metafrontier of Huang, Huang, and Liu (2014) <doi:10.1007/s11123-014-0402-2>, and the metafrontier Malmquist productivity index of O'Donnell, Rao, and Battese (2008) <doi:10.1007/s00181-007-0119-4>. The deterministic metafrontier can be identified by either the minimum sum of absolute deviations (LP) or the minimum sum of squared deviations (QP) criterion. Additional features include panel SFA with time-varying inefficiency, bootstrap confidence intervals for technology gap ratios, a DEA poolability permutation test, latent class metafrontier estimation via the EM algorithm, Murphy-Topel corrected standard errors, convergence diagnostics, import of pre-fitted models from external estimation engines ('sfaR', 'frontier', 'Benchmarking'), and 'ggplot2' visualisation methods. |
| Authors: | Erik Enstad [aut, cre] (ORCID: <https://orcid.org/0009-0006-1053-3849>) |
| Maintainer: | Erik Enstad <[email protected]> |
| License: | GPL (>= 3) |
| Version: | 0.3.1.9000 |
| Built: | 2026-09-24 10:21:23 UTC |
| Source: | https://github.com/iik1/metafrontier |
Generic function that extracts the components needed by
metafrontier from a pre-fitted frontier model.
Methods are provided for sfaR ("sfacross"),
frontier ("frontier"), and Benchmarking
("Farrell") objects, as well as plain lists with the
required fields.
as_metafrontier_model(x, ...)as_metafrontier_model(x, ...)
x |
a fitted frontier model object. |
... |
additional arguments passed to methods. |
metafrontier(models = ...) calls this function internally on
each supplied model, so fitted sfaR or frontier objects
can be passed to metafrontier() directly. Manual conversion
is only needed for hand-built list models. Converting an object that
has already been converted is a no-op, so it is safe to pass
converted objects to metafrontier() as well.
Note that Benchmarking::dea() ("Farrell") objects do
not store the inputs, outputs, or frontier coefficients, so the
converted model carries only efficiency scores and cannot be used
with metafrontier(models = ...); use the formula interface
with method = "dea" instead. Converting a Farrell object
therefore raises a warning.
A list of class "metafrontier_model" with components:
beta, te, X, y, sigma_v,
sigma_u, logLik, hessian, n,
dist.
# Using a named list: mod <- as_metafrontier_model(list( coefficients = c("(Intercept)" = 2, log_x1 = 0.5, log_x2 = 0.3), efficiency = runif(50, 0.7, 1), X = matrix(rnorm(150), 50, 3), y = rnorm(50, 5) )) str(mod)# Using a named list: mod <- as_metafrontier_model(list( coefficients = c("(Intercept)" = 2, log_x1 = 0.5, log_x2 = 0.3), efficiency = runif(50, 0.7, 1), X = matrix(rnorm(150), 50, 3), y = rnorm(50, 5) )) str(mod)
Autoplot Method for Bootstrap TGR Objects
## S3 method for class 'boot_tgr' autoplot(object, which = c("distribution", "ci"), ...)## S3 method for class 'boot_tgr' autoplot(object, which = c("distribution", "ci"), ...)
object |
a |
which |
character. |
... |
additional arguments. |
A ggplot object.
if (requireNamespace("ggplot2", quietly = TRUE)) { sim <- simulate_metafrontier(n_groups = 2, n_per_group = 50, seed = 42) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group", meta_type = "stochastic") boot <- boot_tgr(fit, R = 50, seed = 1, progress = FALSE) ggplot2::autoplot(boot) }if (requireNamespace("ggplot2", quietly = TRUE)) { sim <- simulate_metafrontier(n_groups = 2, n_per_group = 50, seed = 42) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group", meta_type = "stochastic") boot <- boot_tgr(fit, R = 50, seed = 1, progress = FALSE) ggplot2::autoplot(boot) }
Autoplot Method for Malmquist Meta Objects
## S3 method for class 'malmquist_meta' autoplot(object, which = c("decomposition", "tgr_evolution", "mpi_trend"), ...)## S3 method for class 'malmquist_meta' autoplot(object, which = c("decomposition", "tgr_evolution", "mpi_trend"), ...)
object |
a |
which |
character. Which plot:
|
... |
additional arguments. |
A ggplot object.
if (requireNamespace("ggplot2", quietly = TRUE)) { panels <- lapply(1:3, function(t) { sim <- simulate_metafrontier(n_groups = 2, n_per_group = 30, seed = 42 + t) sim$data$time <- t sim$data$id <- seq_len(nrow(sim$data)) sim$data }) pdata <- do.call(rbind, panels) malm <- malmquist_meta(log_y ~ log_x1 + log_x2, data = pdata, group = "group", time = "time") ggplot2::autoplot(malm, which = "decomposition") }if (requireNamespace("ggplot2", quietly = TRUE)) { panels <- lapply(1:3, function(t) { sim <- simulate_metafrontier(n_groups = 2, n_per_group = 30, seed = 42 + t) sim$data$time <- t sim$data$id <- seq_len(nrow(sim$data)) sim$data }) pdata <- do.call(rbind, panels) malm <- malmquist_meta(log_y ~ log_x1 + log_x2, data = pdata, group = "group", time = "time") ggplot2::autoplot(malm, which = "decomposition") }
Creates diagnostic and summary plots for metafrontier objects using ggplot2.
## S3 method for class 'metafrontier' autoplot( object, which = c("tgr", "efficiency", "decomposition", "frontier"), ... )## S3 method for class 'metafrontier' autoplot( object, which = c("tgr", "efficiency", "decomposition", "frontier"), ... )
object |
a |
which |
character. Which plot to produce:
|
... |
additional arguments (currently unused). |
A ggplot object.
if (requireNamespace("ggplot2", quietly = TRUE)) { sim <- simulate_metafrontier(n_groups = 2, n_per_group = 50, seed = 42) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group") ggplot2::autoplot(fit, which = "tgr") ggplot2::autoplot(fit, which = "decomposition") }if (requireNamespace("ggplot2", quietly = TRUE)) { sim <- simulate_metafrontier(n_groups = 2, n_per_group = 50, seed = 42) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group") ggplot2::autoplot(fit, which = "tgr") ggplot2::autoplot(fit, which = "decomposition") }
Computes bootstrap confidence intervals for TGR estimates from a fitted metafrontier model. Supports both parametric (residual resampling) and nonparametric (case resampling) bootstraps.
boot_tgr( object, R = 999, type = c("parametric", "nonparametric"), level = 0.95, ci_type = c("percentile", "bca"), seed = NULL, progress = TRUE, ncores = 1L, ... )boot_tgr( object, R = 999, type = c("parametric", "nonparametric"), level = 0.95, ci_type = c("percentile", "bca"), seed = NULL, progress = TRUE, ncores = 1L, ... )
object |
a |
R |
integer. Number of bootstrap replications (default 999). |
type |
character. |
level |
numeric. Confidence level (default 0.95). |
ci_type |
character. |
seed |
optional integer seed for reproducibility. |
progress |
logical. Show progress bar (default |
ncores |
integer. Number of CPU cores for parallel bootstrap
(default 1, sequential). Requires the |
... |
additional arguments passed to |
The parametric bootstrap keeps the design fixed and redraws the
response, so column i of tgr_boot is the TGR of DMU
i in every replicate. It returns observation-level intervals
(ci) as well as group-level intervals.
The nonparametric bootstrap resamples rows with replacement within
each group, stacks the resampled rows group by group in the order of
groups, and refits the model. Column j of
tgr_boot is then the j-th resampled unit, a random
draw from group boot_group[j], not DMU j. The
group-level intervals are computed over these position blocks and
do not depend on the row order of the data. No observation-level
intervals are returned (ci is NULL): a column is not
tied to any DMU, and evaluating the original DMUs against each
bootstrap frontier instead is, for DEA, the naive bootstrap, which
is inconsistent (Kneip, Simar and Wilson, 2008). For SFA fits,
observation-level intervals are available from the parametric
bootstrap.
Group-level intervals are percentile intervals of the within-group
mean (ci_group) and median (ci_group_median) of the
TGR across replicates. Rows dropped from the fit because of missing
values are left out of both bootstraps.
An object of class "boot_tgr" containing:
R x n matrix of bootstrapped TGR values. For the
parametric bootstrap, column i is DMU i; for the
nonparametric bootstrap, column j is the j-th
resampled unit (see Details).
original TGR estimates
n x 2 matrix of observation-level confidence intervals
(parametric bootstrap), or NULL (nonparametric
bootstrap)
data frame of group-level mean TGR intervals
data frame of group-level median TGR intervals
number of successful replications
requested number of replications
bootstrap type used
CI type used
confidence level
group of each element of tgr_original
group of each column of tgr_boot
group labels
Kneip, A., Simar, L. and Wilson, P.W. (2008). Asymptotics and consistent bootstraps for DEA estimators in nonparametric frontier models. Econometric Theory, 24(6), 1663–1697. doi:10.1017/S0266466608080651
sim <- simulate_metafrontier(n_groups = 2, n_per_group = 100, seed = 42) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group", meta_type = "stochastic") boot <- boot_tgr(fit, R = 50, seed = 1) print(boot) confint(boot) # Nonparametric bootstrap: group-level intervals only boot_np <- boot_tgr(fit, R = 50, type = "nonparametric", seed = 1) boot_np$ci_group boot_np$ci_group_mediansim <- simulate_metafrontier(n_groups = 2, n_per_group = 100, seed = 42) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group", meta_type = "stochastic") boot <- boot_tgr(fit, R = 50, seed = 1) print(boot) confint(boot) # Nonparametric bootstrap: group-level intervals only boot_np <- boot_tgr(fit, R = 50, type = "nonparametric", seed = 1) boot_np$ci_group boot_np$ci_group_median
Reports the convergence status of every estimation stage of a fitted metafrontier model: each group-level frontier and the metafrontier itself. This makes it easy to verify that all optimisers (MLE) and mathematical programmes (LP/QP) finished successfully before interpreting technology gap ratios, confidence intervals, or efficiency decompositions.
check_convergence(object, ...) ## S3 method for class 'metafrontier' check_convergence(object, ...) ## S3 method for class 'lc_metafrontier' check_convergence(object, ...) ## S3 method for class 'malmquist_meta' check_convergence(object, ...)check_convergence(object, ...) ## S3 method for class 'metafrontier' check_convergence(object, ...) ## S3 method for class 'lc_metafrontier' check_convergence(object, ...) ## S3 method for class 'malmquist_meta' check_convergence(object, ...)
object |
a fitted model object. |
... |
additional arguments passed to methods. |
For groups supplied via the models argument of
metafrontier the convergence status of the external
fitter is not tracked, and the corresponding rows carry
NA with an explanatory note.
A data frame of class "metafrontier_convergence"
with one row per estimation stage and columns:
stage label, e.g. "group: G1" or
"metafrontier"
how the stage was estimated: "MLE",
"LP", "QP", "QP (barrier)",
"DEA", or "external"
the integer convergence code returned by the
optimiser (0 indicates success); NA for DEA stages
and externally fitted groups
logical convergence indicator; for DEA
stages TRUE unless any efficiency score is
NA (infeasible programme); NA for externally
fitted groups
additional detail, e.g. the number of infeasible DEA programmes
sim <- simulate_metafrontier(n_groups = 2, n_per_group = 50, seed = 42) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group") check_convergence(fit)sim <- simulate_metafrontier(n_groups = 2, n_per_group = 50, seed = 42) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group") check_convergence(fit)
Extract Coefficients from a Metafrontier Model
## S3 method for class 'metafrontier' coef(object, which = c("meta", "group"), extraPar = FALSE, ...)## S3 method for class 'metafrontier' coef(object, which = c("meta", "group"), extraPar = FALSE, ...)
object |
a |
which |
character. |
extraPar |
logical. If |
... |
additional arguments (currently unused). |
A named numeric vector (which = "meta") or a named
list of numeric vectors (which = "group").
sim <- simulate_metafrontier(n_groups = 2, n_per_group = 50, seed = 42) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group", meta_type = "stochastic") coef(fit) coef(fit, extraPar = TRUE) coef(fit, which = "group", extraPar = TRUE)sim <- simulate_metafrontier(n_groups = 2, n_per_group = 50, seed = 42) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group", meta_type = "stochastic") coef(fit) coef(fit, extraPar = TRUE) coef(fit, which = "group", extraPar = TRUE)
Computes Wald-type confidence intervals for the metafrontier coefficients using the variance-covariance matrix from the stochastic metafrontier.
## S3 method for class 'metafrontier' confint( object, parm, level = 0.95, correction = c("none", "murphy-topel"), ... )## S3 method for class 'metafrontier' confint( object, parm, level = 0.95, correction = c("none", "murphy-topel"), ... )
object |
a |
parm |
a character or integer vector of parameter names or indices. If missing, all frontier coefficients are used. |
level |
the confidence level (default 0.95). |
correction |
character. Passed to |
... |
additional arguments (currently unused). |
A matrix with columns for the lower and upper bounds.
sim <- simulate_metafrontier(n_groups = 2, n_per_group = 50, seed = 42) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group", meta_type = "stochastic") confint(fit) # With Murphy-Topel correction (requires numDeriv): confint(fit, correction = "murphy-topel")sim <- simulate_metafrontier(n_groups = 2, n_per_group = 50, seed = 42) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group", meta_type = "stochastic") confint(fit) # With Murphy-Topel correction (requires numDeriv): confint(fit, correction = "murphy-topel")
Extracts technical efficiency scores from a fitted metafrontier
model. Returns either group-specific efficiency (),
metafrontier efficiency (), or the
technology gap ratio ().
efficiencies(object, ...) ## S3 method for class 'metafrontier' efficiencies(object, type = c("meta", "group", "tgr"), estimator = NULL, ...)efficiencies(object, ...) ## S3 method for class 'metafrontier' efficiencies(object, type = c("meta", "group", "tgr"), estimator = NULL, ...)
object |
a fitted |
... |
additional arguments (currently unused). |
type |
character. The type of efficiency to return:
|
estimator |
optional character. Override the efficiency
estimator used at fit time: |
The fundamental metafrontier decomposition is:
where is efficiency relative to the group frontier
(returned by type = "group") and is the
technology gap ratio (returned by type = "tgr").
A numeric vector of efficiency scores of length
nobs(object).
technology_gap_ratio, metafrontier
set.seed(42) sim <- simulate_metafrontier(n_groups = 2, n_per_group = 100) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group") # Group-level efficiency te <- efficiencies(fit, type = "group") # Metafrontier efficiency te_star <- efficiencies(fit, type = "meta") # Verify decomposition: TE* = TE x TGR tgr <- efficiencies(fit, type = "tgr") all.equal(te_star, te * tgr)set.seed(42) sim <- simulate_metafrontier(n_groups = 2, n_per_group = 100) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group") # Group-level efficiency te <- efficiencies(fit, type = "group") # Metafrontier efficiency te_star <- efficiencies(fit, type = "meta") # Verify decomposition: TE* = TE x TGR tgr <- efficiencies(fit, type = "tgr") all.equal(te_star, te * tgr)
Estimates a metafrontier model where group membership is unobserved, using an EM algorithm to jointly estimate class membership probabilities, class-specific frontier parameters, and the metafrontier.
latent_class_metafrontier( formula, data, n_classes = 2, dist = c("hnormal", "tnormal", "exponential"), meta_type = c("deterministic", "stochastic"), n_starts = 10, max_iter = 200, tol = 1e-06, seed = NULL, control = list(), ... )latent_class_metafrontier( formula, data, n_classes = 2, dist = c("hnormal", "tnormal", "exponential"), meta_type = c("deterministic", "stochastic"), n_starts = 10, max_iter = 200, tol = 1e-06, seed = NULL, control = list(), ... )
formula |
a |
data |
a data frame. |
n_classes |
integer. Number of latent classes (default 2). |
dist |
distribution of the inefficiency term. |
meta_type |
metafrontier type for Stage 2. |
n_starts |
integer. Number of random initializations (default 10). The best is selected by log-likelihood. |
max_iter |
integer. Maximum EM iterations (default 200). |
tol |
numeric. Convergence tolerance on marginal LL (default 1e-6). |
seed |
optional integer seed. |
control |
list of control parameters for the optimiser. |
... |
additional arguments. |
Latent class estimation is available for SFA-based metafrontiers
only: the EM posterior class probabilities require a parametric
observation-level likelihood, which DEA does not provide. For DEA
fits with observed groups, see poolability_test.
The EM algorithm iterates between:
E-step: compute posterior class membership probabilities for each observation using Bayes' rule
M-step: update class-specific frontier parameters via weighted MLE, and update class proportions
Multiple random starts (n_starts) are used to avoid local optima.
The run with the highest marginal log-likelihood is selected.
After convergence, observations are assigned to classes via MAP
(maximum a posteriori), and a standard metafrontier is fitted on the
MAP classes.
An object of class "lc_metafrontier" containing:
MAP class assignment per observation
n x C matrix of posterior probabilities
class mixing proportions
list of class-specific parameter vectors
list of class-specific model summaries
the fitted metafrontier object on MAP classes
marginal log-likelihood at convergence
Bayesian Information Criterion
number of classes
number of EM iterations used
sim <- simulate_metafrontier(n_groups = 2, n_per_group = 80, seed = 42) lc <- latent_class_metafrontier( log_y ~ log_x1 + log_x2, data = sim$data, n_classes = 2, n_starts = 3, seed = 123 ) print(lc) summary(lc) coef(lc, which = "meta") efficiencies(lc, type = "tgr")sim <- simulate_metafrontier(n_groups = 2, n_per_group = 80, seed = 42) lc <- latent_class_metafrontier( log_y ~ log_x1 + log_x2, data = sim$data, n_classes = 2, n_starts = 3, seed = 123 ) print(lc) summary(lc) coef(lc, which = "meta") efficiencies(lc, type = "tgr")
Computes the metafrontier Malmquist total factor productivity (TFP) index and its three-way decomposition into technical efficiency change (TEC), technology gap change (TGC), and metafrontier technical change (TC*) for panel data, following O'Donnell, Rao, and Battese (2008).
malmquist_meta( formula = NULL, data = NULL, group = NULL, time = NULL, id = NULL, method = c("dea", "sfa"), dist = c("hnormal", "tnormal", "exponential"), estimator = c("bc88", "jlms"), orientation = c("output", "input"), rts = c("crs", "vrs", "drs", "irs", "fdh"), control = list(), ... )malmquist_meta( formula = NULL, data = NULL, group = NULL, time = NULL, id = NULL, method = c("dea", "sfa"), dist = c("hnormal", "tnormal", "exponential"), estimator = c("bc88", "jlms"), orientation = c("output", "input"), rts = c("crs", "vrs", "drs", "irs", "fdh"), control = list(), ... )
formula |
an object of class |
data |
a data frame containing all variables, plus the grouping and time variables. |
group |
a character string naming the column in |
time |
a character string naming the column in |
id |
optional. A character string naming the column in
|
method |
character. |
dist |
character. Distribution of the inefficiency term
when |
estimator |
character. Technical efficiency estimator used
when |
orientation |
character. |
rts |
character. Returns to scale assumption:
|
control |
a list of control parameters for the SFA optimiser. |
... |
additional arguments (currently unused). |
The metafrontier Malmquist TFP index decomposes productivity change into three components:
where:
: technical
efficiency change relative to the group frontier
: technology gap change,
capturing whether a group's frontier is catching up to or
falling behind the metafrontier
: metafrontier technical change, measuring
the shift of the global production possibility frontier
Firm matching: when id is supplied, firms are
matched across consecutive periods by identifier within each
technology group. Duplicated (id, period) combinations within a
group are an error. Observations without a within-group match in
the adjacent period, either because the panel is unbalanced or
because a firm switches group between periods, are dropped, and a
single consolidated warning reports the number dropped per period
pair. When id is NULL, firms are matched by row
position within each group; this is valid only for balanced
panels sorted identically in every period, so a message is
emitted as a reminder, and a warning is issued when group sizes
differ across a period pair (the unmatched observations are
dropped). Supplying id is recommended.
DEA-based computation (method = "dea"): for each
consecutive pair of periods , eight sets of LP
problems are solved: within-group and pooled efficiencies at each
period, plus cross-period evaluations for the geometric mean
formulation of technical change. Distances to the metafrontier
are exact distances to the pooled-data frontier, as in O'Donnell,
Rao and Battese (2008).
SFA-based computation is an approximation
(method = "sfa"): period-specific group SFA frontiers are
estimated, and each observation's metafrontier distance is
approximated by the pointwise maximum of the estimated group
frontier functions evaluated at its inputs; no enveloping
metafrontier is re-estimated. This coincides with the O'Donnell
et al. (2008) metafrontier wherever a single group frontier
dominates, but can understate the metafrontier where group
frontiers cross, which affects TGC and TC*. Prefer
method = "dea" when an exact decomposition is required.
Infeasible cross-period programs: under
rts = "vrs", "drs", "irs", or "fdh",
cross-period LPs can be genuinely infeasible because the
reference technology cannot reach the evaluated observation. Such
cases yield NA (never Inf), are excluded from the
reported means, and are counted in a single consolidated warning;
the counts are stored in the n_infeasible and
infeasible_by_period components. rts = "crs" avoids
the issue, as does the hyperbolic orientation available in
metafrontier.
Note that the standard Malmquist index is not a ‘proper’ (multiplicatively complete and transitive) TFP index in the sense of O'Donnell (2012), so chained comparisons of index levels across more than two periods should be avoided.
An object of class "malmquist_meta", a list
with components:
data frame with columns: id,
group, period_from, period_to,
MPI (metafrontier Malmquist TFP index),
TEC (technical efficiency change),
TGC (technology gap change),
TC (metafrontier technical change). The id
column holds the supplied firm identifiers when id
is given, and the within-group match position otherwise.
data frame with the within-group
Malmquist index decomposition: MPI_group,
EC_group, TC_group
data frame with the metafrontier
Malmquist index: MPI_meta, EC_meta,
TC_meta
data frame with technology gap ratios at each
period endpoint: id, group,
period_from, period_to, TGR_from
(TGR at the start period), TGR_to (TGR at the
end period), and TGC (technology gap change,
TGR_to / TGR_from)
the matched function call
the estimation method used ("dea" or
"sfa")
the orientation used
the returns to scale assumption
group labels
time periods
total number of infeasible cross-period
DEA programs (always 0 for method = "sfa")
data frame with the number of
infeasible cross-period DEA programs per period pair
(method = "dea" only)
O'Donnell, C.J., Rao, D.S.P. and Battese, G.E. (2008). Metafrontier frameworks for the study of firm-level efficiencies and technology ratios. Empirical Economics, 34(2), 231–255. doi:10.1007/s00181-007-0119-4
O'Donnell, C.J. (2012). An aggregate quantity framework for measuring and decomposing productivity change. Journal of Productivity Analysis, 38(3), 255–272. doi:10.1007/s11123-012-0275-1
# Simulate panel data for 2 groups, 3 time periods set.seed(42) panels <- lapply(1:3, function(t) { sim <- simulate_metafrontier( n_groups = 2, n_per_group = 30, tech_gap = c(0, 0.3 + 0.05 * t), sigma_u = c(0.2, 0.3), seed = 42 + t ) sim$data$time <- t sim$data$id <- seq_len(nrow(sim$data)) sim$data }) panel_data <- do.call(rbind, panels) # Compute metafrontier Malmquist index, matching firms by id malm <- malmquist_meta( log_y ~ log_x1 + log_x2, data = panel_data, group = "group", time = "time", id = "id" ) summary(malm)# Simulate panel data for 2 groups, 3 time periods set.seed(42) panels <- lapply(1:3, function(t) { sim <- simulate_metafrontier( n_groups = 2, n_per_group = 30, tech_gap = c(0, 0.3 + 0.05 * t), sigma_u = c(0.2, 0.3), seed = 42 + t ) sim$data$time <- t sim$data$id <- seq_len(nrow(sim$data)) sim$data }) panel_data <- do.call(rbind, panels) # Compute metafrontier Malmquist index, matching firms by id malm <- malmquist_meta( log_y ~ log_x1 + log_x2, data = panel_data, group = "group", time = "time", id = "id" ) summary(malm)
Estimates group-specific frontiers and a metafrontier that envelops all group technologies. Supports both SFA-based (parametric) and DEA-based (nonparametric) approaches, with deterministic (Battese, Rao, and O'Donnell, 2004) or stochastic (Huang, Huang, and Liu, 2014) metafrontier estimation.
metafrontier( formula = NULL, data = NULL, group = NULL, method = c("sfa", "dea"), meta_type = c("deterministic", "stochastic"), dist = c("hnormal", "tnormal", "exponential"), orientation = c("output", "input"), rts = c("crs", "vrs", "drs", "irs", "fdh"), models = NULL, panel = NULL, panel_dist = c("bc92", "bc95"), type = c("radial", "directional", "hyperbolic"), direction = c("proportional", "output", "input"), control = list(), estimator = c("bc88", "jlms"), objective = c("lp", "qp"), engine = c("internal", "sfaR", "frontier", "Benchmarking"), slack = FALSE, ... )metafrontier( formula = NULL, data = NULL, group = NULL, method = c("sfa", "dea"), meta_type = c("deterministic", "stochastic"), dist = c("hnormal", "tnormal", "exponential"), orientation = c("output", "input"), rts = c("crs", "vrs", "drs", "irs", "fdh"), models = NULL, panel = NULL, panel_dist = c("bc92", "bc95"), type = c("radial", "directional", "hyperbolic"), direction = c("proportional", "output", "input"), control = list(), estimator = c("bc88", "jlms"), objective = c("lp", "qp"), engine = c("internal", "sfaR", "frontier", "Benchmarking"), slack = FALSE, ... )
formula |
an object of class |
data |
a data frame containing all variables in the formula
and the grouping variable. Ignored if |
group |
a character string naming the column in |
method |
character. The frontier estimation method for
group-specific models: |
meta_type |
character. The method for estimating the
metafrontier: |
dist |
character. Distribution of the one-sided inefficiency
term in SFA models. One of |
orientation |
character. For DEA: |
rts |
character. Returns to scale for DEA: |
models |
an optional named list of pre-fitted group-specific
frontier models (objects from sfaR or frontier, or
hand-built lists). Fitted model objects are converted
automatically via |
panel |
an optional list with components |
panel_dist |
character. Panel SFA model: |
type |
character. For DEA: |
direction |
direction vector for DDF. Either a character
preset ( |
control |
a named list of control parameters passed to
|
estimator |
character. Technical efficiency estimator for
SFA models: |
objective |
character. Identification criterion for the
deterministic metafrontier: |
engine |
character. Estimation backend for the group
frontiers: |
slack |
logical. For radial DEA, compute second-stage input
and output slacks (with the radial score held fixed) against
both the group and the pooled reference sets. Default
|
... |
additional arguments passed to the group-level estimation functions. |
The metafrontier framework decomposes efficiency relative to a global technology into two components:
where is efficiency relative to the group frontier and
is the technology gap ratio measuring how close the
group frontier is to the metafrontier.
The deterministic metafrontier is identified by one of the two
criteria proposed by Battese, Rao, and O'Donnell (2004), subject in
both cases to the constraint that the metafrontier envelops all
group frontiers: minimising the sum of absolute deviations, which
reduces to a linear programme because the envelope constraints
force every deviation to be non-negative (O'Donnell, Rao, and
Battese, 2008, Eqs. 23-25), or minimising the sum of squared
deviations, a convex quadratic programme. The LP
(objective = "lp", the default) is solved via
lpSolveAPI; the QP (objective = "qp") is solved
exactly via quadprog when available, with an adaptive-barrier
fallback via constrOptim().
The stochastic metafrontier (Huang, Huang, and Liu, 2014) replaces
this with a second-stage SFA, providing a distributional framework
for inference on the TGR.
Convergence and failure handling: estimation stops with an
error only when no usable estimate exists (for example, when both
the BFGS and Nelder-Mead optimisers fail for a group frontier).
When an optimiser stops at a non-zero convergence code, the fitted
object is returned with a warning and the code is recorded; use
check_convergence or summary() to verify all
estimation stages before interpreting technology gap ratios,
confidence intervals, or productivity decompositions. Infeasible
DEA programmes yield NA efficiency scores, accompanied by a
warning and counted by check_convergence.
Note on standard errors (stochastic metafrontier):
The stochastic metafrontier is a two-stage estimator. Stage 2 treats
the fitted group frontier values as data, so the reported standard
errors, confidence intervals, and variance-covariance matrix do not
account for estimation uncertainty from Stage 1 (the
generated-regressor problem; see Murphy and Topel, 1985). Use
vcov(fit, correction = "murphy-topel") or bootstrap-based
confidence intervals via boot_tgr for corrected
inference.
Note on frontier orientation (SFA path):
The SFA estimation path assumes a production frontier
(). Cost frontiers ()
are not currently supported via the SFA path. The DEA path supports
both orientation = "output" and orientation = "input".
An object of class "metafrontier" (with subclass
"metafrontier_sfa" or "metafrontier_dea"),
containing:
the matched function call
list of fitted group-specific models
estimated metafrontier parameters
list of group-specific coefficient vectors
technology gap ratios for each observation
group-specific technical efficiency
metafrontier technical efficiency (TE* = TE x TGR)
log-likelihoods of group models
number of observations per group and total
group labels
estimation method used
metafrontier type used
integer convergence code for the
metafrontier stage (0 = success; optim
codes for the stochastic metafrontier and the QP barrier
fallback; 0 for a successful LP or DEA solution). Each SFA
group model in group_models additionally carries its
own convergence code. Use
check_convergence to inspect all stages.
the estimation choices used for the fit
Battese, G.E., Rao, D.S.P. and O'Donnell, C.J. (2004). A metafrontier production function for estimation of technical efficiencies and technology gaps for firms operating under different technologies. Journal of Productivity Analysis, 21(1), 91–103. doi:10.1023/B:PROD.0000012454.06094.29
Huang, C.J., Huang, T.-H. and Liu, N.-H. (2014). A new approach to estimating the metafrontier production function based on a stochastic frontier framework. Journal of Productivity Analysis, 42(3), 241–254. doi:10.1007/s11123-014-0402-2
O'Donnell, C.J., Rao, D.S.P. and Battese, G.E. (2008). Metafrontier frameworks for the study of firm-level efficiencies and technology ratios. Empirical Economics, 34(2), 231–255. doi:10.1007/s00181-007-0119-4
# Simulate metafrontier data set.seed(42) sim <- simulate_metafrontier(n_groups = 2, n_per_group = 100) # Estimate deterministic SFA metafrontier (BRO 2004) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group", method = "sfa", meta_type = "deterministic") summary(fit) # Technology gap ratios tgr <- technology_gap_ratio(fit) summary(tgr)# Simulate metafrontier data set.seed(42) sim <- simulate_metafrontier(n_groups = 2, n_per_group = 100) # Estimate deterministic SFA metafrontier (BRO 2004) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group", method = "sfa", meta_type = "deterministic") summary(fit) # Technology gap ratios tgr <- technology_gap_ratio(fit) summary(tgr)
Produces diagnostic and summary plots for a fitted metafrontier model.
## S3 method for class 'metafrontier' plot(x, which = c("tgr", "efficiency", "decomposition", "frontier"), ...)## S3 method for class 'metafrontier' plot(x, which = c("tgr", "efficiency", "decomposition", "frontier"), ...)
x |
a |
which |
character. Type of plot to produce:
|
... |
additional graphical parameters passed to base plotting functions. |
Invisibly returns x.
set.seed(42) sim <- simulate_metafrontier(n_groups = 2, n_per_group = 100) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group") plot(fit, which = "tgr") plot(fit, which = "decomposition")set.seed(42) sim <- simulate_metafrontier(n_groups = 2, n_per_group = 100) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group") plot(fit, which = "tgr") plot(fit, which = "decomposition")
Tests the null hypothesis that all groups share a common frontier (i.e., the metafrontier coincides with all group frontiers) against the alternative that group-specific frontiers differ. For SFA-based metafrontiers a likelihood ratio test is used; for DEA-based metafrontiers a permutation test is used.
poolability_test(object, B = 199, seed = NULL, ...)poolability_test(object, B = 199, seed = NULL, ...)
object |
a fitted |
B |
integer. Number of permutation replicates for the DEA permutation test (default 199). Ignored for SFA objects. |
seed |
integer or |
... |
additional arguments (currently unused). |
Likelihood ratio test (SFA). The LR statistic is:
where is the log-likelihood of the pooled (single
frontier) model and are the group-specific
log-likelihoods. Under H0, the statistic follows a chi-squared
distribution with degrees of freedom equal to
, where is the
total number of parameters across all group-specific models and
is the number of parameters in the pooled model.
For groups each with frontier parameters plus
distributional parameters, this equals
where includes
frontier coefficients, , and
(and for truncated-normal). This test requires a
likelihood and is therefore only available for SFA-based
metafrontiers.
Permutation test (DEA). DEA has no likelihood, so the
poolability hypothesis is assessed by a permutation test. Under the
null of a single pooled technology, group labels are exchangeable:
reassigning observations to groups at random should not
systematically change the distance between the group frontiers and
the metafrontier. The observed statistic is the mean technology gap,
, and its null distribution
is approximated by refitting the metafrontier on B random
permutations of the group labels. The p-value is
, following the
aggregate-efficiency inference logic of Simar and Zelenyuk (2007).
The smoothed subsampling approach of Kneip, Simar, and Wilson (2016)
is the asymptotically rigorous alternative for testing hypotheses in
nonparametric production models; the permutation test offered here
is a computationally simple approximation. The default B = 199
is a pragmatic choice; p-values have resolution , so
increase B for finer resolution.
A list of class "htest" with components:
the test statistic (LR statistic for SFA; the
mean technology gap, ,
for DEA)
degrees of freedom (SFA) or the effective number of permutation replicates (DEA)
p-value of the test
description of the test
Simar, L. and Zelenyuk, V. (2007). Statistical inference for aggregates of Farrell-type efficiencies. Journal of Applied Econometrics, 22(7), 1367–1394. doi:10.1002/jae.991
Kneip, A., Simar, L. and Wilson, P.W. (2016). Testing hypotheses in nonparametric models of production. Journal of Business & Economic Statistics, 34(3), 435–456. doi:10.1080/07350015.2015.1049747
set.seed(42) sim <- simulate_metafrontier(n_groups = 2, n_per_group = 200, tech_gap = c(0, 0.5)) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group") poolability_test(fit) # DEA permutation test fit_dea <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group", method = "dea") poolability_test(fit_dea, B = 99, seed = 1)set.seed(42) sim <- simulate_metafrontier(n_groups = 2, n_per_group = 200, tech_gap = c(0, 0.5)) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group") poolability_test(fit) # DEA permutation test fit_dea <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group", method = "dea") poolability_test(fit_dea, B = 99, seed = 1)
Computes predicted frontier values at given input levels using either the metafrontier or a group-specific frontier.
## S3 method for class 'metafrontier' predict(object, newdata = NULL, type = c("meta", "group"), ...)## S3 method for class 'metafrontier' predict(object, newdata = NULL, type = c("meta", "group"), ...)
object |
a |
newdata |
an optional data frame of new inputs. If omitted, the training data predictions are returned. |
type |
character. |
... |
additional arguments (currently unused). |
A numeric vector of predicted frontier values.
sim <- simulate_metafrontier(n_groups = 2, n_per_group = 50, seed = 42) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group", meta_type = "stochastic") pred <- predict(fit) # Out-of-sample prediction: newdata <- data.frame(log_x1 = c(1, 2), log_x2 = c(1.5, 2.5)) predict(fit, newdata = newdata)sim <- simulate_metafrontier(n_groups = 2, n_per_group = 50, seed = 42) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group", meta_type = "stochastic") pred <- predict(fit) # Out-of-sample prediction: newdata <- data.frame(log_x1 = c(1, 2), log_x2 = c(1.5, 2.5)) predict(fit, newdata = newdata)
Prints a compact overview of a fitted metafrontier model: the estimation method and metafrontier type, the efficiency estimator and identification objective (where applicable), the groups and their sample sizes, group log-likelihoods, mean technology gap ratio by group, and a one-line convergence status.
## S3 method for class 'metafrontier' print(x, ...)## S3 method for class 'metafrontier' print(x, ...)
x |
a |
... |
additional arguments (currently unused). |
Invisibly returns x.
sim <- simulate_metafrontier(n_groups = 2, n_per_group = 50, seed = 42) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group") print(fit)sim <- simulate_metafrontier(n_groups = 2, n_per_group = 50, seed = 42) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group") print(fit)
Fits a latent class metafrontier model for each value in
n_classes_range and tabulates the Bayesian information
criterion (BIC) and marginal log-likelihood of each fit. The
optimal number of classes minimises BIC. Fits that fail are
silently dropped from the table. Because the EM algorithm can
converge to local optima, the ranking is sensitive to the number
of random starts: pass n_starts (forwarded to
latent_class_metafrontier) and increase it for a
more reliable comparison across class counts.
select_n_classes(formula, data, n_classes_range = 2:5, ...)select_n_classes(formula, data, n_classes_range = 2:5, ...)
formula |
formula. |
data |
data frame. |
n_classes_range |
integer vector of class counts to try. |
... |
additional arguments passed to
|
A data frame with columns n_classes, BIC,
and marginal_ll.
sim <- simulate_metafrontier(n_groups = 2, n_per_group = 80, seed = 42) bic_table <- select_n_classes( log_y ~ log_x1 + log_x2, data = sim$data, n_classes_range = 2:3, n_starts = 3, seed = 42 ) print(bic_table)sim <- simulate_metafrontier(n_groups = 2, n_per_group = 80, seed = 42) bic_table <- select_n_classes( log_y ~ log_x1 + log_x2, data = sim$data, n_classes_range = 2:3, n_starts = 3, seed = 42 ) print(bic_table)
Generates synthetic data from a known metafrontier data-generating process. Each group frontier lies weakly below the metafrontier, consistent with groups facing different restrictions of a common metatechnology (Battese, Rao and O'Donnell, 2004). Useful for Monte Carlo simulations, package testing, and teaching.
simulate_metafrontier( n_groups = 2L, n_per_group = 100L, n_inputs = 2L, beta_meta = NULL, tech_gap = NULL, sigma_u = NULL, sigma_v = 0.2, seed = NULL, beta_groups = NULL, input_means = NULL, input_corr = NULL )simulate_metafrontier( n_groups = 2L, n_per_group = 100L, n_inputs = 2L, beta_meta = NULL, tech_gap = NULL, sigma_u = NULL, sigma_v = 0.2, seed = NULL, beta_groups = NULL, input_means = NULL, input_corr = NULL )
n_groups |
integer. Number of technology groups (default 2). |
n_per_group |
integer or integer vector. Number of observations
per group. If a single value, the same number is used for all
groups. If a vector, must be of length |
n_inputs |
integer. Number of input variables (default 2). |
beta_meta |
numeric vector. Metafrontier coefficients
(including intercept). Length must be |
tech_gap |
numeric vector of length |
sigma_u |
numeric vector of length |
sigma_v |
numeric. Standard deviation of the symmetric noise term. Default: 0.2. |
seed |
integer or |
beta_groups |
optional group-specific frontier coefficients,
including slopes: either an |
input_means |
optional |
input_corr |
optional |
By default the group frontiers share the metafrontier slopes and
differ only in their intercepts, so the true technology gap ratio
(TGR) is constant within each group and equals
exp(-tech_gap[g]). When beta_groups is supplied the
group frontiers may differ in their slopes, in which case no single
log-linear metafrontier envelops all groups: the tightest log-linear
envelope is then a pseudo-true quantity. The returned
true_tgr is instead computed observation by observation
against the pointwise maximum over the group frontiers,
, which is
guaranteed to lie in (0, 1]. The true group frontier for each firm
is , true_te is generated exactly as in the
default design, and true_te_star = true_te * true_tgr. In
this case params$beta_meta is NULL and
params$beta_groups holds the supplied coefficients.
By default the log-inputs are drawn i.i.d. from a uniform
distribution on [0, 5], identically across groups. Supplying
input_means and/or input_corr switches to normal
log-inputs with standard deviation 5 / sqrt(12) (matching the
spread of the uniform draws), centred at input_means[g, ]
(2.5 for every group and input when input_means is
NULL). When input_corr is supplied the draws are
multivariate normal with that correlation matrix; when it is
NULL but input_means is given, the inputs are drawn
independently.
A list with components:
a data frame with columns log_y, log_x1,
log_x2, ..., group, and the true underlying values
a list of the true parameters used for generation
sim <- simulate_metafrontier(n_groups = 3, n_per_group = 200, sigma_u = c(0.2, 0.4, 0.3)) str(sim$data) table(sim$data$group) # The true metafrontier coefficients sim$params$beta_meta # Group-specific slopes: per-observation true TGR sim2 <- simulate_metafrontier( beta_groups = rbind(c(1.0, 0.5, 0.2), c(0.9, 0.6, 0.1)) ) range(sim2$data$true_tgr)sim <- simulate_metafrontier(n_groups = 3, n_per_group = 200, sigma_u = c(0.2, 0.4, 0.3)) str(sim$data) table(sim$data$group) # The true metafrontier coefficients sim$params$beta_meta # Group-specific slopes: per-observation true TGR sim2 <- simulate_metafrontier( beta_groups = rbind(c(1.0, 0.5, 0.2), c(0.9, 0.6, 0.1)) ) range(sim2$data$true_tgr)
Generates a simulated panel dataset with known metafrontier parameters for Monte Carlo studies and testing. Implements the Battese-Coelli 1992 DGP with time-varying inefficiency.
simulate_panel_metafrontier( n_groups = 2, n_firms_per_group = 30, n_periods = 5, beta_meta = c(1, 0.5, 0.3), tech_gap = NULL, sigma_u = 0.3, sigma_v = 0.2, eta = 0.05, seed = NULL, attrition = 0 )simulate_panel_metafrontier( n_groups = 2, n_firms_per_group = 30, n_periods = 5, beta_meta = c(1, 0.5, 0.3), tech_gap = NULL, sigma_u = 0.3, sigma_v = 0.2, eta = 0.05, seed = NULL, attrition = 0 )
n_groups |
integer. Number of technology groups. |
n_firms_per_group |
integer. Number of firms per group. |
n_periods |
integer. Number of time periods. |
beta_meta |
numeric vector. Metafrontier coefficients. |
tech_gap |
numeric vector of group technology gaps. |
sigma_u |
numeric. Standard deviation of the firm effect. |
sigma_v |
numeric. Standard deviation of noise. |
eta |
numeric. Time-decay parameter for BC92. |
seed |
integer or NULL. Random seed. |
attrition |
numeric in [0, 0.5]. Probability that each
firm-period observation after a firm's first period is dropped
independently, producing an unbalanced panel. Every firm's first
period is always kept, so all firms remain in the data. The
attrition draws are made after all other random numbers, so
|
A list with components:
data frame with columns: firm, year,
group, log_y, log_x1, log_x2,
true_te, true_u, true_v
list of true parameter values used in generation,
including attrition and the realised
attrition_share
sim <- simulate_panel_metafrontier( n_groups = 2, n_firms_per_group = 20, n_periods = 5, seed = 42 ) head(sim$data) str(sim$params) # An unbalanced panel with roughly 20% attrition sim_unbal <- simulate_panel_metafrontier(seed = 42, attrition = 0.2) table(table(sim_unbal$data$firm))sim <- simulate_panel_metafrontier( n_groups = 2, n_firms_per_group = 20, n_periods = 5, seed = 42 ) head(sim$data) str(sim$params) # An unbalanced panel with roughly 20% attrition sim_unbal <- simulate_panel_metafrontier(seed = 42, attrition = 0.2) table(table(sim_unbal$data$firm))
Computes group-level summaries of technical efficiency (TE),
technology gap ratio (TGR), and metafrontier efficiency (TE*),
full coefficient tables for each group frontier (including
variance parameters and, for BC92 panels, eta, all with
standard errors where a Hessian is available), the metafrontier
coefficient table (with Murphy-Topel corrected standard errors
where applicable), and a per-stage convergence table.
## S3 method for class 'metafrontier' summary(object, ...)## S3 method for class 'metafrontier' summary(object, ...)
object |
a |
... |
additional arguments (currently unused). |
An object of class "summary.metafrontier": a list
with components
the matched call of the original fit
estimation method ("sfa" or "dea")
metafrontier type ("deterministic" or
"stochastic")
character vector of group labels
named vector of observation counts (total and per group)
named list of coefficient matrices, one per
group, with columns Estimate, Std. Error,
z value, and Pr(>|z|) where standard errors are
available (empty list for DEA fits)
metafrontier coefficient matrix in the same
format, or NULL for DEA fits
data frame of TGR statistics by group, as
returned by tgr_summary
data frame with mean TE, mean TGR, and mean TE* by group
named vector of group log-likelihoods, or
NULL
Stage 2 log-likelihood of the stochastic
metafrontier, or NULL
data frame with columns stage,
code, and converged recording the optimiser
status of each estimation stage, or NULL if
unavailable; see check_convergence
sim <- simulate_metafrontier(n_groups = 2, n_per_group = 50, seed = 42) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group", meta_type = "stochastic") s <- summary(fit) print(s)sim <- simulate_metafrontier(n_groups = 2, n_per_group = 50, seed = 42) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group", meta_type = "stochastic") s <- summary(fit) print(s)
Extracts the technology gap ratios (TGR) from a fitted metafrontier model. The TGR measures how close a group's production frontier is to the global metafrontier at each observation's input mix.
technology_gap_ratio(object, by_group = TRUE, ...)technology_gap_ratio(object, by_group = TRUE, ...)
object |
a fitted |
by_group |
logical. If |
... |
additional arguments (currently unused). |
The technology gap ratio is defined as:
for SFA-based metafrontiers, and
for DEA-based metafrontiers.
Under the deterministic metafrontier and DEA, TGR lies in (0, 1] by construction. Under the stochastic metafrontier of Huang, Huang, and Liu (2014), TGR can exceed 1 for some observations because the metafrontier need not envelop the group frontiers at every point.
A TGR of 1 means the group frontier coincides with the metafrontier at that input mix. Values less than 1 indicate a technology gap. Since each group technology is a restricted subset of the common metatechnology (Battese, Rao and O'Donnell, 2004), the gap reflects the restrictions a group faces (regulation, environment, endowments) rather than a fundamentally different technology.
If by_group = TRUE, a named list of numeric vectors.
If by_group = FALSE, a numeric vector of length
nobs(object).
metafrontier, efficiencies.metafrontier
set.seed(42) sim <- simulate_metafrontier(n_groups = 2, n_per_group = 100) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group") tgr <- technology_gap_ratio(fit) lapply(tgr, summary)set.seed(42) sim <- simulate_metafrontier(n_groups = 2, n_per_group = 100) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group") tgr <- technology_gap_ratio(fit) lapply(tgr, summary)
Prints a summary table of TGR statistics by group. The underlying
observation-level TGR values are the same as those returned by
efficiencies(object, type = "tgr").
tgr_summary(object, ...)tgr_summary(object, ...)
object |
a fitted |
... |
additional arguments (currently unused). |
A data frame with columns: Group, N, Mean, SD, Min, Q1, Median, Q3, Max.
efficiencies.metafrontier,
technology_gap_ratio, boot_tgr
sim <- simulate_metafrontier(n_groups = 2, n_per_group = 50, seed = 42) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group", method = "sfa", meta_type = "deterministic") tgr_summary(fit)sim <- simulate_metafrontier(n_groups = 2, n_per_group = 50, seed = 42) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group", method = "sfa", meta_type = "deterministic") tgr_summary(fit)
Returns the variance-covariance matrix of the Stage 2
(metafrontier) coefficients, or, with which = "group", the
per-group matrices from the Stage 1 maximum likelihood fits.
NULL is returned when no Stage 2 Hessian exists: the
deterministic metafrontier is fitted by LP/QP optimisation and has
no sampling variance in this framework, so which = "meta"
returns NULL with a warning; with which = "group",
list entries are NULL for groups without a stored Hessian
(e.g. externally fitted models). DEA-based metafrontiers are
nonparametric and vcov() signals an error; use
boot_tgr for inference instead.
## S3 method for class 'metafrontier' vcov( object, correction = c("none", "murphy-topel"), which = c("meta", "group"), extraPar = FALSE, ... )## S3 method for class 'metafrontier' vcov( object, correction = c("none", "murphy-topel"), which = c("meta", "group"), extraPar = FALSE, ... )
object |
a |
correction |
character. |
which |
character. |
extraPar |
logical. If |
... |
additional arguments (currently unused). |
A variance-covariance matrix (which = "meta"), a
named list of matrices (which = "group"), or NULL
if unavailable.
Murphy, K.M. and Topel, R.H. (1985). Estimation and inference in two-step econometric models. Journal of Business & Economic Statistics, 3(4), 370–379.
sim <- simulate_metafrontier(n_groups = 2, n_per_group = 50, seed = 42) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group", meta_type = "stochastic") vcov(fit) vcov(fit, correction = "murphy-topel")sim <- simulate_metafrontier(n_groups = 2, n_per_group = 50, seed = 42) fit <- metafrontier(log_y ~ log_x1 + log_x2, data = sim$data, group = "group", meta_type = "stochastic") vcov(fit) vcov(fit, correction = "murphy-topel")