Standardisation and Decomposition of Rates as Products

Rate as products of 2 factors\(^*\)



\(^*\) “factors” here may be better worded as “component parts”. It’s nothing to do with R’s as.factor()

Rates as products of 3 factors

Decomposition - Das Gupta

standardisation:

  • what the rates would be if factor A was asis, but the other factors were at the average configuration’ (i.e., the weighted mean of all possible combinations of those factors across the two populations)

decomposition:

  • how much of \(\Delta R\) is due to \(\Delta A\), averaged over all possible ways of moving from \(R_1\) to \(R_2\).

hypothetical rates letting one factor move and holding others constant

comparison of hypothetical rates to determine contribution of each factor

phew…

Take-away:

  • neutrality: doesn’t favour one population as the standard

  • symmetry: order of factors doesn’t matter

  • \(\Delta R = \Delta A_{std} + \Delta B_{std} + \ldots + \Delta K_{std}\)

Decomposition - {DasGuptR}

Why?

  • developed because we shared an office back in 2019.

  • implements all of Das Gupta’s 1993 manual:

    • K factors
    • arbitrary rate functions (not just products)
    • crossclassified data structures
    • N populations

Decomposition - {DasGuptR}

  • We’ve been pleasantly surprised by the usage (n.b, expectations were low!)

    • Understanding tuberculosis rates in Brazil
    • Comparing contribution of different factors to epilepsy burden across different sociodemographic indices
    • Changes in population composition affecting rates of ‘deaths of despair’ (USA)
    • Understanding the labour market. It’s in Portuguese, but this technical note from Charles Correa at the Central Bank of Brazil has some excellent examples and explanations.

Decomposition - {DasGuptR}

Workflow

dgnpop(x = <data>,
       pop = "...",
       factors = c("..."),
       
       id_vars = c("..."),
       crossclassified = "...",
       ratefunction = "..."
)

Decomposition tables:

dgnpop(...) |> dg_table()

Time series plots:

dgnpop(...) |> dg_plot()

Decomposition - {DasGuptR}

2 factor

library(tibble)

mydat <- tribble(
  ~pop,~psq,~pgr,
  "P1", 5/15, 3/5,
  "P2", 10/15, 8/10,
) 
mydat
# A tibble: 2 × 3
  pop     psq   pgr
  <chr> <dbl> <dbl>
1 P1    0.333   0.6
2 P2    0.667   0.8
library(DasGuptR)

dgres <- dgnpop(x = mydat,
       pop = "pop",
       factors = c("psq","pgr"))

head(dgres)
  rate pop std.set factor
1 0.20  P1    <NA>  crude
2 0.53  P2    <NA>  crude
3 0.23  P1      P2    psq
4 0.47  P2      P1    psq
5 0.30  P1      P2    pgr
6 0.40  P2      P1    pgr

^ these are the rates for each population (both crude and standardised rates)

The value of the factor column denotes the part of the rate that is not held at the average.

Decomposition - {DasGuptR}

2 factor

library(tibble)

mydat <- tribble(
  ~pop,~psq,~pgr,
  "P1", 5/15, 3/5,
  "P2", 10/15, 8/10,
) 
mydat
# A tibble: 2 × 3
  pop     psq   pgr
  <chr> <dbl> <dbl>
1 P1    0.333   0.6
2 P2    0.667   0.8
library(DasGuptR)

dgres <- dgnpop(x = mydat,
       pop = "pop",
       factors = c("psq","pgr"))

dg_table(dgres)
        P1   P2 diff decomp
psq   0.23 0.47 0.23     70
pgr   0.30 0.40 0.10     30
crude 0.20 0.53 0.33    100

Decomposition - {DasGuptR}

Das Gupta tables

Decomposition - {DasGuptR}

3 factor

library(tibble)

mydat <- tribble(
  ~pop,~pcol,~psq,~pgr,
  "P1", 11/15, 4/11, 3/4,
  "P2", 13/15, 10/13, 8/10,
) 
mydat
# A tibble: 2 × 4
  pop    pcol   psq   pgr
  <chr> <dbl> <dbl> <dbl>
1 P1    0.733 0.364  0.75
2 P2    0.867 0.769  0.8 
library(DasGuptR)

dgres <- dgnpop(x = mydat,
       pop = "pop",
       factors = c("pcol","psq","pgr"))

head(dgres)
  rate pop std.set factor
1 0.20  P1    <NA>  crude
2 0.53  P2    <NA>  crude
3 0.32  P1      P2   pcol
4 0.38  P2      P1   pcol
5 0.23  P1      P2    psq
6 0.48  P2      P1    psq

Decomposition - {DasGuptR}

3 factor

library(tibble)

mydat <- tribble(
  ~pop,~pcol,~psq,~pgr,
  "P1", 11/15, 4/11, 3/4,
  "P2", 13/15, 10/13, 8/10,
) 
mydat
# A tibble: 2 × 4
  pop    pcol   psq   pgr
  <chr> <dbl> <dbl> <dbl>
1 P1    0.733 0.364  0.75
2 P2    0.867 0.769  0.8 
library(DasGuptR)

dgres <- dgnpop(x = mydat,
       pop = "pop",
       factors = c("pcol","psq","pgr"))

dg_table(dgres)
        P1   P2  diff decomp
pcol  0.32 0.38 0.059   17.6
psq   0.23 0.48 0.252   75.5
pgr   0.34 0.37 0.023    6.9
crude 0.20 0.53 0.333  100.0

End