help opl_tb_cba

Title

opl_tb_cba - Welfare-maximizing cost-benefit analysis with threshold policies

Syntax

opl_tb_cba tauvar [if] [in],
cost(varname)
select(varlist)
[lambda(#)
npoints(#)
custom(numlist)
custompolicy(varname)
generate(prefix)
graph
replace]

where tauvar contains estimated individual treatment effects and
select() contains one or two variables used to construct the threshold
policy.

Description

opl_tb_cba learns an interpretable threshold-based treatment policy
that maximizes weighted social surplus:

Q(pi;lambda) = sum_i pi_i [tau_i - lambda c_i].

Here, tau_i is the estimated individual treatment effect,
c_i is the individual treatment cost, and lambda controls the
weight assigned to costs.

The command first computes the unconstrained first-best policy:

pi_i^ = 1(tau_i - lambda c_i > 0).

It then searches for the best policy within a restricted and interpretable
class of upper-threshold rules. With one selection variable, the policy is

pi_i(g_1) = 1(z_{1i} >= g_1).

With two selection variables, the policy is

pi_i(g_1,g_2) = 1(z_{1i} >= g_1 and z_{2i} >= g_2).

The selection variables are internally standardized to the interval [0,1].
The optimal threshold or threshold pair is found by exhaustive grid search.
Thresholds are returned both on the standardized scale and on the original
scale of the selection variables.

The command reports the first-best policy, the optimal threshold policy, and
the welfare loss caused by restricting treatment assignment to the selected
threshold-policy class.

Options

cost(varname) specifies the variable containing individual
treatment costs. This option is required.

select(varlist) specifies one or two numeric variables used
to construct the threshold policy. One variable produces a one-threshold
rule; two variables produce a two-threshold rule. Constant selection
variables are not allowed.

lambda(#) specifies the nonnegative weight attached to
treatment costs. The default is lambda(1). Setting lambda(0)
maximizes total treatment benefit without penalizing costs.

npoints(#) specifies the number of equally spaced threshold
values evaluated over [0,1] for each selection variable. The default is
npoints(101). With two selection variables, the command evaluates
# squared candidate policies.

custom(numlist) evaluates user-specified threshold policies
in addition to the optimum. With one selection variable, each number defines
a separate threshold policy. With two selection variables, exactly two
numbers must be supplied, defining one threshold pair. All thresholds must
lie in [0,1].

custompolicy(varname) evaluates a user-supplied binary
policy variable. The variable must contain only 0 and 1 in the estimation
sample.

generate(prefix) generates policy and auxiliary variables
using the specified prefix.

The following variables are created:

prefix_fb first-best treatment policy

prefix_opt optimal threshold policy

prefix_surplus individual weighted surplus

prefix_z1 first selection variable standardized to [0,1]

prefix_z2 second standardized selection variable, when specified

When custom() is specified, the command also generates custom policy
variables. With one selection variable, these are named
prefix_custom1, prefix_custom2, and so on. With two
selection variables, the generated variable is named
prefix_custom.

graph displays the optimal threshold policy. With one selection
variable, the graph plots individual weighted surplus against the standardized
selection variable. With two selection variables, it displays selected and
nonselected observations in the two-dimensional selection space.

replace allows existing generated variables with the requested names to
be replaced.

Policy evaluation measures

For each policy, the following quantities are computed:

N_treated number of treated observations

coverage share of valid observations assigned to treatment

total_benefit sum of estimated treatment effects among treated observations

total_cost sum of treatment costs among treated observations

Q weighted social surplus

ATET average estimated treatment effect among treated observations

avg_cost average treatment cost among treated observations

avg_surplus average weighted surplus among treated observations

Weighted social surplus is

Q = total benefit - lambda x total cost.

Stored results

opl_tb_cba is eclass and stores the following results:

e(N) number of valid observations

e(lambda) cost-weight parameter

e(nselect) number of selection variables

e(npoints) number of grid points per selection variable

e(npolicies) number of candidate threshold policies evaluated

e(x1_min) minimum of the first selection variable

e(x1_max) maximum of the first selection variable

e(x2_min) minimum of the second selection variable

e(x2_max) maximum of the second selection variable

e(threshold1) optimal first threshold on the standardized scale

e(threshold1_lev) optimal first threshold on the original scale

e(threshold2) optimal second threshold on the standardized scale

e(threshold2_lev) optimal second threshold on the original scale

First-best policy results:

e(N_fb) number treated

e(coverage_fb) treatment coverage

e(total_benefit_fb) total treatment benefit

e(total_cost_fb) total treatment cost

e(Q_fb) weighted social surplus

e(ATET_fb) average treatment effect among treated

e(avg_cost_fb) average treatment cost

e(avg_surplus_fb) average weighted surplus

Optimal threshold-policy results:

e(N_opt) number treated

e(coverage_opt) treatment coverage

e(total_benefit_opt) total treatment benefit

e(total_cost_opt) total treatment cost

e(Q_opt) weighted social surplus

e(ATET_opt) average treatment effect among treated

e(avg_cost_opt) average treatment cost

e(avg_surplus_opt) average weighted surplus

e(Q_loss) welfare loss relative to the first-best policy

e(Q_ratio) ratio of threshold-policy welfare to first-best welfare

The command also stores:

e(grid) matrix containing all candidate threshold policies and their outcomes

e(custom) matrix containing results for policies specified in custom()

e(custompolicy) matrix containing results for custompolicy()

e(has_custompolicy) indicator that a custom policy was evaluated

e(tauvar) treatment-effect variable

e(costvar) cost variable

e(selectvars) selection variables

e(generate) generated-variable prefix

e(policytype) policy class, equal to threshold

e(direction) threshold direction, equal to upper

When custompolicy() is specified, additional scalars with suffix
_custompolicy report its coverage, benefit, cost, welfare, ATET,
average cost, average surplus, welfare loss, and welfare ratio.

Postestimation

Postestimation tools are available after opl_tb_cba.

See opl_frontier_tb for constructing, saving, and graphing the policy
frontiers associated with the estimated threshold-policy model.

Examples

One-dimensional threshold policy:

sysuse data_opl_tb_cba_1, clear

opl_tb_cba tau, cost(cost) select(x1) lambda(1) npoints(101) custompolicy(D) custom(.30 .50 .70) generate(opl1) replace

opl_frontier_tb, frame(welfare_frontier) graph replace

Two-dimensional threshold policy:

sysuse data_opl_tb_cba_2, clear

opl_tb_cba tau, cost(cost) select(x1 x2) lambda(1) npoints(51) custompolicy(D) custom(.30 .30) generate(opl2) graph replace

opl_frontier_tb, frame(welfare_frontier_2d) graph bands(15) splinepoints(150) replace

Acknowledgment

The development of this software was supported by FOSSR (Fostering Open
Science in Social Science Research), a project funded by the European Union -
NextGenerationEU under the NPRR Grant agreement n. MURIR0000008.

Author

Giovanni Cerulli

IRCrES-CNR

Research Institute for Sustainable Economic Growth,
National Research Council of Italy

E-mail: giovanni.cerulli@cnr.it

Also see

Online: opl