Reference-set data envelopment analysis with psdea

The idea

A DEA score is a distance to a frontier, and the frontier is built from peers. `psdea» makes the peer set an argument. The weight matrix is used only through its non-zero pattern: a non-zero off-diagonal entry means that the column unit may enter the frontier of the row unit, and the unit itself is always included.

A three-unit example

Three units use one unit of input and produce 1, 2 and 4 units of output.

library(psdea)
X <- matrix(c(1, 1, 1), nrow = 1)
Y <- matrix(c(1, 2, 4), nrow = 1)
round(psdea_sbm(X, Y)$eff, 4)
## [1] 0.25 0.50 1.00

The scores are the ratio to the best observed ratio, 4. Restricting unit 1 to units 1 and 2 lowers the best ratio to 2:

W <- matrix(c(0, 1, 0,
              1, 0, 1,
              0, 1, 0), 3, 3, byrow = TRUE)
round(psdea_sbm(X, Y, W = W)$eff_loc, 4)
## [1] 0.5 0.5 1.0

A panel

data(psdea_china_energy)
d <- subset(psdea_china_energy, year == 2015 & code <= 8)
W <- psdea_w_contiguity[1:8, 1:8]
fit <- psdea_panel(d, "gdp_real", c("capital", "energy"), "year",
                   id = "code", bad = "co2", W = W)
fit
## 
## Reference-set DEA
##   observations : 8 
##   returns      : crs 
##   mean eff (unrestricted): 0.6041 
##   mean eff (restricted)  : 0.8547 
##   mean gap ratio         : 0.7135 
##   mean local share       : 0.3539 
##   units on the frontier  : 2

The two shares decompose the shortfall, and they are missing on the frontier because the denominator is zero there:

fit[, c("eff", "eff_loc", "s_local", "s_gap")]
## 
## Reference-set DEA
##   observations : 8 
##   returns      : 
##   mean eff (unrestricted): 0.6041 
##   mean eff (restricted)  : 0.8547
## Warning in mean.default(x$tgr, na.rm = TRUE): argument is not numeric or
## logical: returning NA
##   mean gap ratio         : NA 
##   mean local share       : 0.3539 
##   units on the frontier  : 2

Learning the peers

When the analyst has no prior on who the peers are, the matrix can be built by sparse non-negative reconstruction of each unit’s bundle:

Wl <- psdea_learn_data(d, c("capital", "energy", "gdp_real"), lambda = 0.05, by = "year")
attr(Wl, "n_peers")
## [1] 2
fit_l <- psdea_panel(d, "gdp_real", c("capital", "energy"), "year",
                     id = "code", bad = "co2", W = Wl)
mean(fit_l$tgr, na.rm = TRUE)
## [1] 0.7712359