Funded share of a league-table programme from the budget left after the programmes ranked above it

Funds programme i, the i-th in ascending order of ICER, in full when the budget left after the programmes ranked above it covers its incremental cost, in part when it covers some of that cost, and not at all when nothing is left. The share x_i is the budget left, B less the cumulative cost S_prev of the programmes above, divided by Delta_C_i and held at least 0 and at most 1, and the health it buys is x_i times Delta_E_i. Applied down the table this is the league-table rule of Marseille and colleagues, which Sacristán and colleagues call the fixed budget rule and Dakin and Tsiachristas identify as the greedy algorithm for the knapsack problem, with the marginal programme part-funded as in the article's worked example. S_i carries the cumulative cost to the next row, and HE-CF-CELT-001 fills the whole table.

Signature

x_i = min(1, max(0, (B - S_prev) / Delta_C_i)); h_i = x_i * Delta_E_i; S_i = S_prev + Delta_C_i
Inputs
InputsDefinitionUnit
BBudget available for the programmes in the tablecurrency
S_prevIncremental cost of every programme ranked above programme i, zero for the firstcurrency
Delta_C_iIncremental cost of programme i against its comparator, above zerocurrency
Delta_E_iIncremental health gain of programme i against its comparator, above zeroQALYs, or DALYs averted
Output
x_iShare of programme i funded, at least 0 and at most 1, with 1 for a programme funded in fullproportion
h_iHealth gained from the funded share of programme iQALYs, or DALYs averted
S_iIncremental cost of programme i and every programme ranked above it, carried to the next rowcurrency

Function

League-table allocation of a fixed budget across independent programmes ranked by ICER

Takes the incremental cost Delta_C_i and incremental health gain Delta_E_i of each of a set of independent programmes, each measured against its own comparator, and a fixed budget B. It returns the share of each programme funded when programmes are funded in ascending order of ICER until the budget is exhausted, the health the budget buys, the critical ratio of the last programme funded and, under the alternative fixed ratio rule, the budget that a stated threshold implies. Each programme's ratio is the two-option ICER of HE-FM-ICER-001, or the ratio against doing nothing of HE-FM-ACER-002 when doing nothing is the comparator, and is not restated here. A league table ranks independent programmes competing for one budget, while mutually exclusive options for the same patients are ranked on the cost-effectiveness frontier (HE-FN-CEF-001, HE-CF-CEF-001), and the table takes such a set at its sequential ratios along the frontier (HE-FM-CEA-001). Ties and cost-saving programmes follow the dominance rule HE-FM-DOM-001, the threshold as marginal spending over marginal health is HE-FM-CET-001, and the health a new programme displaces at a threshold, Delta_C divided by k, and its incremental net health benefit are HE-FM-CET-002. This package adds the funded share of each programme, the critical ratio, the fill for programmes that must be funded whole and the budget implied by a fixed ratio, with a computational function that fills the table for any number of programmes. Notation follows the Cost-Effectiveness League Table article.

Computational function

  • Computational function for filling a fixed budget down a cost-effectiveness league table

    Takes the names, incremental costs and incremental health gains of any number of independent programmes and a budget, sorts the programmes in ascending order of ICER and applies the funded share of HE-FM-CELT-001 row by row, or the whole-programme test of HE-FM-CELT-003 when programmes cannot be split. It returns each programme's ICER and share, the health bought, the spending, the budget left and the critical ratio of HE-FM-CELT-002. The inputs are lists of programmes, not the single row of the formula. The Math / Code line shows four divisible programmes already in ICER order, and the R and Python versions take any number of programmes and do the sorting.

    Inputs and outputs: name is the label of each programme; Delta_C is its incremental cost against its comparator, above zero, in currency; Delta_E is its incremental health gain, above zero, in QALYs or DALYs averted; B is the budget in currency; whole is TRUE when programmes must be funded whole. In the Math / Code line Delta_C_1 to Delta_C_4 and Delta_E_1 to Delta_E_4 are four programmes in ICER order, S_1, S_2 and S_3 the cumulative costs, x_1 to x_4 the shares, H the health bought and spend the spending. The R and Python versions return the programmes in ICER order with ratio and share, the health, the spending, the budget left and the critical ratio.

    Assumption: Programmes are independent and each is measured against the comparator it would replace (HE-AS-CELT-001). A programme that dominates its comparator under HE-FM-DOM-001 is adopted before the call and its saving added to B, since a negative incremental cost would give it a share of zero. Programmes with equal ICERs keep their input order, which changes nothing for divisible programmes but can change the result for whole ones. In whole mode a programme that does not fit is passed over (HE-AS-CELT-007), and the critical ratio returned is the ICER of the least cost-effective programme adopted.

    Worked example (Article's four programmes and GBP 900,000): A, B and C are funded in full and 0.375 of D, giving 97.5 QALYs for the whole budget, with a critical ratio of GBP 20,000 per QALY, as in step 1 of the article. B = 900000; Delta_C_1 = 200000; Delta_E_1 = 40; Delta_C_2 = 300000; Delta_E_2 = 30; Delta_C_3 = 250000; Delta_E_3 = 20; Delta_C_4 = 400000; Delta_E_4 = 20; S_1 = 200000; S_2 = 500000; S_3 = 750000; x_1 = 1; x_2 = 1; x_3 = 1; x_4 = 0.375; H = 97.5; spend = 900000

    Worked example (Budget of GBP 700,000): With an illustrative smaller budget C receives 0.8 of its cost and D nothing, giving 86 QALYs and a critical ratio of GBP 12,500 per QALY. B = 700000; Delta_C_1 = 200000; Delta_E_1 = 40; Delta_C_2 = 300000; Delta_E_2 = 30; Delta_C_3 = 250000; Delta_E_3 = 20; Delta_C_4 = 400000; Delta_E_4 = 20; S_1 = 200000; S_2 = 500000; S_3 = 750000; x_1 = 1; x_2 = 1; x_3 = 0.8; x_4 = 0; H = 86; spend = 700000

    Worked example (Budget above the cost of the whole table): With an illustrative GBP 1,200,000 every programme is funded in full for 110 QALYs and GBP 50,000 is left, a limiting case in which the budget does not bind. B = 1200000; Delta_C_1 = 200000; Delta_E_1 = 40; Delta_C_2 = 300000; Delta_E_2 = 30; Delta_C_3 = 250000; Delta_E_3 = 20; Delta_C_4 = 400000; Delta_E_4 = 20; S_1 = 200000; S_2 = 500000; S_3 = 750000; x_1 = 1; x_2 = 1; x_3 = 1; x_4 = 1; H = 110; spend = 1150000

    Worked example (Article's whole programmes P, Q and R, for the R and Python code): In whole mode with GBP 1,000,000, P is funded and neither Q nor R fits, giving 60 QALYs with GBP 400,000 left, as in step 3 of the article. The Math / Code line covers divisible programmes only, so this example is for reading against the R and Python versions, and its calculator form is HE-EX-CELT-007 under HE-FM-CELT-003. celt_fill(c("P", "Q", "R"), c(600000, 500000, 500000), c(60, 40, 40), 1000000, whole = TRUE) returns health 60, spend 600000 and unspent 400000.

    Excel: With one row per programme from row 2, sorted by ICER with Data, Sort, incremental costs in column B, QALYs in column C and the ICER =B2/C2 in column D, enter =SUM(B$1:B1) in E2 for the cost of the programmes above, the header in B1 counting as zero, =MIN(1,MAX(0,(Budget-E2)/B2)) in F2 for the share and =F2*C2 in G2 for the health, and fill down. For four programmes =SUMPRODUCT(F2:F5,C2:C5) returns the health and =SUMPRODUCT(MAX((F2:F5>0)*D2:D5)) the critical ratio. For whole programmes the share in F2 becomes =--(SUMPRODUCT(B$1:B1,F$1:F1)+B2<=Budget), which tests the cost of the programmes already funded.

    R: celt_fill <- function(name, Delta_C, Delta_E, B, whole = FALSE) { r <- Delta_C/Delta_E; o <- order(r); name <- name[o]; Delta_C <- Delta_C[o]; Delta_E <- Delta_E[o]; r <- r[o]; x <- numeric(length(r)); left <- B; for (i in seq_along(r)) { x[i] <- if (whole) as.numeric(Delta_C[i] <= left) else min(1, max(0, left/Delta_C[i])); left <- left-x[i]*Delta_C[i] }; list(table = data.frame(programme = name, icer = r, share = x), health = sum(x*Delta_E), spend = sum(x*Delta_C), unspent = left, critical_ratio = if (any(x > 0)) max(r[x > 0]) else NA) } Programmes may be given in any order.

    Python: def celt_fill(name, Delta_C, Delta_E, B, whole=False): o = sorted(range(len(Delta_C)), key=lambda i: Delta_C[i]/Delta_E[i]); x = _celt_shares([Delta_C[i] for i in o], B, whole); r = [Delta_C[i]/Delta_E[i] for i in o]; spend = sum(s*Delta_C[i] for s, i in zip(x, o)); return [(name[i], r[k], x[k]) for k, i in enumerate(o)], sum(s*Delta_E[i] for s, i in zip(x, o)), spend, B-spend, max([r[k] for k in range(len(o)) if x[k] > 0], default=None) with the helper def _celt_shares(c, left, whole): return [] if not c else (lambda s: [s] + _celt_shares(c[1:], left-s*c[0], whole))(float(c[0] <= left) if whole else min(1.0, max(0.0, left/c[0]))) Plain Python with no imports, returning the programmes as tuples of name, ICER and share, then the health, the spending, the budget left and the critical ratio.

    Test (Spending equals the budget or the cost of the whole table): With the shares in F2 to F5 and the costs in B2 to B5, the spending on divisible programmes equals the budget when the budget binds and the cost of every programme when it does not. Expected result TRUE. FALSE shows a share formula without the floor at zero, which at GBP 700,000 gives D a share of minus 0.125 and spending of GBP 650,000, or one without the cap at 1, which at GBP 1,200,000 gives spending of GBP 3,350,000. Excel check =ABS(SUMPRODUCT(F2:F5,B2:B5)-MIN(Budget,SUM(B2:B5)))<0.01

    Test (Article's 97.5 QALYs reproduced): With the article's four programmes and GBP 900,000 the health in the fill is 97.5 QALYs. Expected result TRUE. FALSE shows rows left sorted by incremental cost with the dearest first, D, B, C and A, which buy 66 QALYs. Excel check =ABS(SUMPRODUCT(F2:F5,C2:C5)-97.5)<0.000001

    Common error (Leaving a cost-saving programme out of the table): An illustrative programme that saves GBP 50,000 and gains 5 QALYs against its comparator dominates it. Left out, the budget of GBP 900,000 buys 97.5 QALYs. Adopted first with its saving added, GBP 950,000 funds A, B, C and half of D, and the total is 105 QALYs, 7.5 more (computed here for illustration).

    Source: Marseille E, Larson B, Kazi DS, Kahn JG, Rosen S. Thresholds for the cost-effectiveness of interventions: alternative approaches. Bulletin of the World Health Organization. 2015;93(2):118-124. Section League tables, on ranking at least somewhat scalable interventions by ICER and selecting from the lowest ICER down the list until the budget is exhausted. Dakin H, Tsiachristas A. Rationing in an era of multiple tight constraints: is cost-utility analysis still fit for purpose? Applied Health Economics and Health Policy. 2024;22(3):315-329. Section 2.2, on the league table as the greedy algorithm for the knapsack problem, and section 2.1, on the 0-1 knapsack problem and on programmes that cannot be partially adopted. Sacristán JA, Abellán-Perpiñán JM, Dilla T, Soto J, Oliva J. Some reflections on the use of inappropriate comparators in CEA. Cost Effectiveness and Resource Allocation. 2020;18:29. Introduction, on the fixed budget rule and the critical ratio.

    S_1 = Delta_C_1; S_2 = S_1 + Delta_C_2; S_3 = S_2 + Delta_C_3; x_1 = min(1, max(0, B / Delta_C_1)); x_2 = min(1, max(0, (B - S_1) / Delta_C_2)); x_3 = min(1, max(0, (B - S_2) / Delta_C_3)); x_4 = min(1, max(0, (B - S_3) / Delta_C_4)); H = x_1 * Delta_E_1 + x_2 * Delta_E_2 + x_3 * Delta_E_3 + x_4 * Delta_E_4; spend = x_1 * Delta_C_1 + x_2 * Delta_C_2 + x_3 * Delta_C_3 + x_4 * Delta_C_4

Try this function

Implementations

  • Excel

    Funded share and health of one league-table row from named cells

    With the budget in Budget, the cumulative incremental cost of the programmes ranked above in CumCostAbove and the programme's incremental cost and QALYs in IncCost and IncQALY, the first formula returns the share, held in a cell named FundedShare, the second the health bought, held in FundedHealth, and the third the cumulative cost for the next row.

    =MIN(1,MAX(0,(Budget-CumCostAbove)/IncCost)); =FundedShare*IncQALY; =CumCostAbove+IncCost

Assumptions

  • Independent programmes each measured against the comparator it would replace

    Each Delta_C_i and Delta_E_i is measured against the comparator that programme would replace, on one perspective, price year and health measure. Where a programme comes in mutually exclusive versions for the same patients, the versions enter at their sequential ratios along the cost-effectiveness frontier (HE-FM-CEA-001, HE-CF-CEF-001), each against the next cheaper frontier option, as in the WHO-CHOICE malaria table that Marseille and colleagues reproduce, where each option after the first is compared with the next cheapest.

  • Positive increments in ascending ICER order, with ties and cost-saving programmes

    Programmes are numbered in ascending order of ICER and Delta_C_i and Delta_E_i are both above zero, so x_i is defined. A programme that costs no more than its comparator and gives no less health, and is strictly better on one of the two, dominates it under HE-FM-DOM-001, ties included, and is adopted outside the table with any saving added to B. Programmes with equal ICERs buy the same health per unit of currency, so their order leaves total health unchanged when they are divisible (derived), while for whole programmes the order can matter (HE-FM-CELT-003).

  • Divisible programmes at a constant cost per unit of health with no interdependence

    The marginal programme can be part-funded, each extra unit of currency buys the same health within a programme, and funding one programme leaves the costs and effects of the others unchanged. These are the article's conditions for the greedy rule to give the best allocation, in line with the scalability condition of Marseille and colleagues, and they are the restrictive assumptions that Stinnett and Paltiel relax with mathematical programming for returns to scale, partial and complete indivisibility and programme interdependence.

Worked examples

  • Programme A at the top of the article's league table funded in full

    In the article's illustrative table a health authority has GBP 900,000 for four independent programmes A, B, C and D, each compared with no programme. A heads the table at GBP 5,000 per QALY, nothing is spent above it and its GBP 200,000 fits, so it is funded in full for 40 QALYs.

    B = 900000; S_prev = 0; Delta_C_i = 200000; Delta_E_i = 40; x_i = 1; h_i = 40; S_i = 200000
  • Marginal programme D part-funded with the GBP 150,000 left

    After A, B and C, which cost GBP 750,000 in all, GBP 150,000 is left for D, which costs GBP 400,000, so 0.375 of D is funded for 7.5 QALYs, as in step 1 of the article. The cumulative cost passed on is GBP 1,150,000, the last figure in the article's table.

    B = 900000; S_prev = 750000; Delta_C_i = 400000; Delta_E_i = 20; x_i = 0.375; h_i = 7.5; S_i = 1150000
  • Programme N at its true incremental ratio below D left unfunded

    Entered at its true ratio of GBP 30,000 per QALY against the service M it would replace, the article's programme N sits below D with an incremental cost of GBP 300,000 and a gain of 10 QALYs. The cost of the programmes above it, GBP 1,150,000, already exceeds the budget, so its share is zero, a limiting case for the floor at zero.

    B = 900000; S_prev = 1150000; Delta_C_i = 300000; Delta_E_i = 10; x_i = 0; h_i = 0; S_i = 1450000

Common errors

  • Entering a programme at its ratio against no treatment when it would replace a funded service

    The article's programme N costs GBP 700,000 and gives 50 QALYs, GBP 14,000 per QALY against no treatment, which places it between C and D and ahead of D in the fill. It would replace the funded service M (GBP 400,000, 40 QALYs), so its incremental ratio from HE-FM-ICER-001 is GBP 30,000 per QALY and it belongs below D. Switching spends GBP 300,000 for 10 QALYs, while the same sum on D buys 15, so the error loses 5 QALYs, the incremental net health benefit of HE-FM-CET-002 at the GBP 20,000 critical ratio. The test of Birch and Gafni, as Dakin and Tsiachristas describe it, also rejects the switch, since freeing GBP 300,000 from the funded programmes gives up at least 19.5 QALYs, the funded part of D and GBP 150,000 of C, against the 10 gained (computed here for illustration).

  • Counting a programme's own cost in the cumulative cost above it

    Using the cumulative cost through each programme in place of the cost above it moves every row's budget test down one programme. In the article's table C then receives 0.6 of its cost and D nothing, so GBP 650,000 is spent, GBP 250,000 is left over and the budget buys 82 QALYs in place of 97.5 (computed here for illustration).

Sources

  • Marseille and colleagues on funding down the league table until the budget is exhausted

    Marseille E, Larson B, Kazi DS, Kahn JG, Rosen S. Thresholds for the cost-effectiveness of interventions: alternative approaches. Bulletin of the World Health Organization. 2015;93(2):118-124. Section League tables, which states that if all of the interventions considered are at least somewhat scalable they can be ranked into a league table by their ICERs, and that the approach rests on the principle that for any budget health outcomes are maximised if selection begins with the option with the lowest ICER and moves down the list, to successively higher ratios, until the budget is exhausted. Table 1, the WHO-CHOICE malaria table, compares each option after the first with the next cheapest intervention.

    View source →

  • Dakin and Tsiachristas on the league table as a greedy algorithm

    Dakin H, Tsiachristas A. Rationing in an era of multiple tight constraints: is cost-utility analysis still fit for purpose? Applied Health Economics and Health Policy. 2024;22(3):315-329. Section 2.2, headed Cost-effectiveness league tables, a greedy algorithm, which states that given one constraint the league table ranks proposed and current interventions by ICER and adopts interventions from the lowest ICER upwards until the budget is exhausted, equivalent to the greedy algorithm for the knapsack problem, which sorts items by the reciprocal of the ICER. Section 2.3 describes the alternative of Birch and Gafni, which adopts a proposed intervention only if current interventions can be discontinued to free enough funds to cover its cost while generating fewer QALYs than it does.

    View source →

Canonical Identity