| Title: | Data Envelopment Analysis with User-Defined and Learned Reference Sets |
|---|---|
| Description: | Slacks-based data envelopment analysis for panel data in which the reference set is an explicit argument. A user-supplied weight matrix, or a matrix learned from the data by penalised non-negative reconstruction, selects the units that may enter each decision-making unit's frontier. The package reports the unrestricted and the restricted score, the ratio of the two and an exact decomposition of the shortfall into the part the restricted technology can remove and the part it cannot. Moran's I and local indicators of spatial association are provided as diagnostics. All linear programs are solved by a two-phase simplex with Bland's rule implemented in R, so the package needs no compiler. |
| Authors: | Jiachao Peng [aut, cre] |
| Maintainer: | Jiachao Peng <[email protected]> |
| License: | GPL-3 |
| Version: | 1.0.0 |
| Built: | 2026-10-28 19:50:46 UTC |
| Source: | https://github.com/cran/psdea |
Slacks-based data envelopment analysis for panel data in which the reference set is an explicit argument. A weight matrix, supplied by the user or learned from the data, selects the units that may enter each decision-making unit's frontier. The package reports the unrestricted and the restricted score, the ratio of the two, and an exact decomposition of the shortfall into the part the restricted technology can remove and the part it cannot.
The main function is psdea_panel. Weight matrices are built with
psdea_spw or learned with psdea_learn; scores can be
inspected with psdea_moran. Every linear program is solved by a
two-phase revised simplex implemented in R (psdea_lp), so the
package has no compiled code and no dependencies beyond base R.
Tone, K. (2001) A slacks-based measure of efficiency in data envelopment analysis. European Journal of Operational Research 130, 498–509.
A panel of 30 Chinese provinces with the inputs, output and undesirable output
used in the article. Energy, carbon dioxide and gross domestic product for
2023 and 2024 are provisional; the columns whose names begin with
flag_ record whether a value is observed, official or nowcast.
A data frame with 660 rows and 22 variables. The variables used in the
examples are code (1–30, matching the weight matrices), prov,
year, energy (10\,000 tonnes of coal equivalent), capital
(100 million yuan at constant 2003 prices), gdp_real (same units) and
co2 (million tonnes).
Provincial statistical yearbooks and the CEADs emission inventory.
data(psdea_china_energy) str(psdea_china_energy[1:5, c("prov", "year", "energy", "gdp_real")])data(psdea_china_energy) str(psdea_china_energy[1:5, c("prov", "year", "energy", "gdp_real")])
Reconstructs each unit's bundle as a sparse non-negative combination of the other units' bundles by penalised least squares, solved with cyclic coordinate descent. The support of the solution is the peer set.
psdea_learn(Z, lambda = 0.05, maxit = 500L, tol = 1e-4) psdea_learn_data(data, vars, lambda = 0.05, by = NULL)psdea_learn(Z, lambda = 0.05, maxit = 500L, tol = 1e-4) psdea_learn_data(data, vars, lambda = 0.05, by = NULL)
Z |
matrix with units in the columns and standardised inputs and outputs in the rows. |
lambda |
penalty on the sum of the weights. Larger values give sparser peer sets. |
maxit |
maximum number of coordinate-descent sweeps. |
tol |
a weight is treated as zero below this value when counting peers. |
data |
a data frame. |
vars |
names of the variables forming the bundle. |
by |
optional name of the period variable; the matrix is then built for each period and averaged. |
The problem is a penalised non-negative reconstruction, not a convex-hull representation: the weights are not constrained to sum to one and normalising them afterwards does not change the optimisation problem. The peer set is chosen on the same observations that produce the scores, so the matrix is a selection rule, not an estimate of a technology club.
A row-normalised matrix of weights, with attributes n_peers and
iters.
set.seed(1) Z <- matrix(runif(40, 1, 2), 4, 10) W <- psdea_learn(Z, lambda = 0.05) attr(W, "n_peers")set.seed(1) Z <- matrix(runif(40, 1, 2), 4, 10) W <- psdea_learn(Z, lambda = 0.05) attr(W, "n_peers")
Solves subject to and with a two-phase
revised simplex and Bland's rule for pricing.
psdea_lp(A, b, c, maxit = 20000L, tol = 1e-10)psdea_lp(A, b, c, maxit = 20000L, tol = 1e-10)
A |
constraint matrix, |
b |
right-hand side, length |
c |
objective coefficients, length |
maxit |
maximum number of pivots. |
tol |
tolerance used in the pricing and ratio tests. |
A list with x (the solution), obj, it (pivots) and
status: 0 optimal, 1 infeasible, 2 iteration limit reached.
A <- matrix(c(1, 2, -1, 0, 3, 1, 0, -1), 2, 4, byrow = TRUE) psdea_lp(A, c(4, 6), c(1, 1, 0, 0))$obj # 2.8A <- matrix(c(1, 2, -1, 0, 3, 1, 0, -1), 2, 4, byrow = TRUE) psdea_lp(A, c(4, 6), c(1, 1, 0, 0))$obj # 2.8
Moran's and local indicators of spatial association for a vector of
scores, with permutation inference. These are diagnostics: is the
slope of the spatial lag on the score, not a share of variance.
psdea_moran(x, W, nperm = 499L, seed = 1L) psdea_lisa(x, W, nperm = 499L, seed = 1L)psdea_moran(x, W, nperm = 499L, seed = 1L) psdea_lisa(x, W, nperm = 499L, seed = 1L)
x |
numeric vector of scores, one per unit. |
W |
square weight matrix. |
nperm |
number of permutations. |
seed |
seed for the permutations. |
psdea_moran returns a named vector with the observed statistic and its
p-value; psdea_lisa returns a data frame with the local statistic and
its conditional p-value for each unit.
x <- c(1, 2, 3, 4) W <- psdea_spw(c(1, 2, 3), c(2, 3, 4), 1:4) psdea_moran(x, W, nperm = 99)x <- c(1, 2, 3, 4) W <- psdea_spw(c(1, 2, 3), c(2, 3, 4), 1:4) psdea_moran(x, W, nperm = 99)
Estimates a slacks-based measure with undesirable outputs for each period of a panel, once against all units and, when a weight matrix is supplied, once against the units selected by that matrix. Returns the decomposed shortfall.
psdea_panel(data, y, x, year, id = NULL, bad = NULL, W = NULL, rts = c("crs", "vrs")) ## S3 method for class 'psdea' print(x, ...) ## S3 method for class 'psdea' summary(object, ...)psdea_panel(data, y, x, year, id = NULL, bad = NULL, W = NULL, rts = c("crs", "vrs")) ## S3 method for class 'psdea' print(x, ...) ## S3 method for class 'psdea' summary(object, ...)
data |
a data frame in long format, one row per unit and period. |
y |
name of the single desirable output. |
x |
for |
year |
name of the period variable; one frontier is built per period. |
id |
name of the unit identifier. When |
bad |
optional character vector with the names of undesirable outputs. |
W |
optional square matrix of order equal to the number of units in a period. A non-zero off-diagonal entry means that the column unit may enter the frontier of the row unit. The unit itself is always included. |
rts |
either |
object |
an object returned by |
... |
further arguments, currently ignored. |
The shares are and ;
they sum to one and are undefined on the frontier, where the denominator is
zero. They are not equal to .
A data frame of class psdea with the columns id, year,
eff (unrestricted score), eff_loc (restricted score),
tgr (their ratio), s_local and s_gap (the two shares of
the shortfall, missing when the unrestricted score is one) and n_peers
(the size of the reference set).
data(psdea_china_energy) d <- subset(psdea_china_energy, year == 2015 & code <= 6) W <- psdea_w_contiguity[1:6, 1:6] fit <- psdea_panel(d, "gdp_real", c("capital", "energy"), "year", id = "code", bad = "co2", W = W) fit fit$s_local + fit$s_gapdata(psdea_china_energy) d <- subset(psdea_china_energy, year == 2015 & code <= 6) W <- psdea_w_contiguity[1:6, 1:6] fit <- psdea_panel(d, "gdp_real", c("capital", "energy"), "year", id = "code", bad = "co2", W = W) fit fit$s_local + fit$s_gap
Computes the slacks-based measure of Tone (2001) with undesirable outputs for every column of a cross-section, optionally against the restricted reference technology defined by a weight matrix.
psdea_sbm(X, Y, B = NULL, vrs = FALSE, W = NULL)psdea_sbm(X, Y, B = NULL, vrs = FALSE, W = NULL)
X |
matrix of inputs, rows are inputs and columns are units. |
Y |
matrix of desirable outputs, same layout. |
B |
matrix of undesirable outputs, or |
vrs |
logical; variable rather than constant returns to scale. |
W |
optional square weight matrix; see |
A list with eff, and, when W is given, eff_loc,
n_peers, tgr, s_local and s_gap.
Tone, K. (2004) Dealing with undesirable outputs in DEA: a slacks-based measure approach. GRIPS Research Report I-2003-0005.
X <- matrix(c(1, 1, 1), nrow = 1) Y <- matrix(c(1, 2, 4), nrow = 1) psdea_sbm(X, Y)$eff # 0.25 0.50 1.00 W <- matrix(c(0, 1, 0, 1, 0, 1, 0, 1, 0), 3, 3, byrow = TRUE) psdea_sbm(X, Y, W = W)$eff_loc # 0.50 1.00 1.00X <- matrix(c(1, 1, 1), nrow = 1) Y <- matrix(c(1, 2, 4), nrow = 1) psdea_sbm(X, Y)$eff # 0.25 0.50 1.00 W <- matrix(c(0, 1, 0, 1, 0, 1, 0, 1, 0), 3, 3, byrow = TRUE) psdea_sbm(X, Y, W = W)$eff_loc # 0.50 1.00 1.00
Builds a square weight matrix from a table of links, or reads one from a comma-separated file. The matrix is used only through its non-zero pattern.
psdea_spw(from, to, units, row_standardise = TRUE, directed = FALSE) psdea_spw_read(file, units = NULL, row_standardise = TRUE)psdea_spw(from, to, units, row_standardise = TRUE, directed = FALSE) psdea_spw_read(file, units = NULL, row_standardise = TRUE)
from, to
|
vectors of unit names or indices giving the links. |
units |
character vector with the unit names, in the order used by the data; the row and column names of the result follow this order. |
row_standardise |
logical; divide each row by its sum. |
directed |
logical; if |
file |
path to a comma-separated file without header. |
A numeric matrix with row and column names units.
units <- c("A", "B", "C") psdea_spw(c("A", "B"), c("B", "C"), units)units <- c("A", "B", "C") psdea_spw(c("A", "B"), c("B", "C"), units)
Matrices of order 30 used in the article: land-border contiguity (65 links plus one for Hainan), four nearest neighbours, and inverse distance with a median cut-off. Rows and columns follow the province code.
A 30 by 30 numeric matrix, row-standardised.
Own construction from provincial boundaries and capital coordinates.
data(psdea_w_contiguity) table(rowSums(psdea_w_contiguity > 0))data(psdea_w_contiguity) table(rowSums(psdea_w_contiguity > 0))