Home | GLMs | Multilevel | Survival | Demography | Stata | R

Period Life Table Construction

Here's how to reproduce the calculations in Box 3.1 of Preston et a. (p. 49) using Stata as a calculator. (Stata has a ltable command for cohort life tables.)

The input data are counts of the mid-year population and the number of deaths at ages 0,1-4,5-9,...,80-84,85+ for Austrian males in 1992, available in the course website.

. infile age N D using http://data.princeton.edu/eco572/datasets/prestonb31.dat
(19 observations read)

We need the width of the age intervals.

. gen n =  age[_n+1]-age // leaves width of last interval missing
(1 missing value generated)

The calculations are pretty straitforward. The numbers below refer to the numbered steps in the textbook. To ensure full precision I use doubles; floats are good for only about 7 digits and this can be a problem with large numbers such as nLx.

1. We compute death rates dividing events by exposure.

. gen m = D/N

2. Next we need the time lived by deaths (nax). Preston et al. borrow these values for ages 5 to 75 from Keyfitz and Flieger (1971), p.21. I saved those values in a Stata file so I can easily merge them here (after sorting by age)

. sort age

. merge age using http://data.princeton.edu/eco572/datasets/kfnax

(You should list the data to see what you got.) The factors for ages 0-1 and 1-4, however, are based on the Coale-Demeny equations under age 5, which depends on the mortality rate at age 0, so we use cond:

. rename nax a // I am omitting the subscripts for simplicity

. replace a = cond(m[1] >= 0.107,  .330,  .045 + 2.684 * m[1]) in 1
(1 real change made)

. replace a = cond(m[1] >= 0.107, 1.352, 1.651 - 2.816 * m[1]) in 2
(1 real change made)

The value for the last age is not used, but we will replace it anyway to avoid confusion

. replace a = 1/m in -1
(1 real change made)

3. Convert the death rates to probabilities using the nax factors, and
4. Compute survival probabilities as the complement

. gen double q = n * m/(1+(n-a)*m)
(1 missing value generated)

. replace q = 1 in -1
(1 real change made)

. gen double p = 1 - q

5. Generate the survival function starting with a radix of 100,000. Note that each value of lx depends on previous values

. gen double lx = 100000 in 1
(18 missing values generated)

. quietly replace lx = lx[_n-1] * p[_n-1] in 2/-1

6. Generate deaths by differencing the number of survivors and noting that everyone dies in the end

. generate d = lx - lx[_n+1]
(1 missing value generated)

. replace  d = lx in -1
(1 real change made)

7. Compute person-years lived in each age group, which is n for those who survive the age group and nax for those who die

. gen double L = n * lx[_n+1] + a * d // not to be confused with D
(1 missing value generated)

. replace L = lx/m in -1
(1 real change made)

8. Accumulating from the bottom up is a bit tricky because Stata likes to sum from the top down. You could sort the data from oldest to youngest, sum, and then sort again. I will subtract the cumulative sum from the total.

. quietly summarize L

. gen double T = r(sum) - sum(L) + L

9. Finally we compute expectation of life dividing time lived after each age by survivors to that age

. gen e = T/lx

To print the table exactly as in the book we specify a few formats

. format %6.3f a e

. format %8.6f m q p

. format %9.0fc N D lx d L T

. format %8.6f m q p

And we are ready to print our results (in two parts)

. list age N D m a q p

     +----------------------------------------------------------------+
     | age         N       D          m       a          q          p |
     |----------------------------------------------------------------|
  1. |   0    47,925     419   0.008743   0.068   0.008672   0.991328 |
  2. |   1   189,127      70   0.000370   1.626   0.001479   0.998521 |
  3. |   5   234,793      36   0.000153   2.500   0.000766   0.999234 |
  4. |  10   238,790      46   0.000193   3.143   0.000963   0.999037 |
  5. |  15   254,996     249   0.000976   2.724   0.004872   0.995128 |
     |----------------------------------------------------------------|
  6. |  20   326,831     420   0.001285   2.520   0.006405   0.993595 |
  7. |  25   355,086     403   0.001135   2.481   0.005659   0.994341 |
  8. |  30   324,222     441   0.001360   2.601   0.006779   0.993221 |
  9. |  35   269,963     508   0.001882   2.701   0.009368   0.990632 |
 10. |  40   261,971     769   0.002935   2.663   0.014577   0.985423 |
     |----------------------------------------------------------------|
 11. |  45   238,011   1,154   0.004849   2.698   0.023975   0.976025 |
 12. |  50   261,612   1,866   0.007133   2.676   0.035082   0.964918 |
 13. |  55   181,385   2,043   0.011263   2.645   0.054861   0.945139 |
 14. |  60   187,962   3,496   0.018600   2.624   0.089062   0.910938 |
 15. |  65   153,832   4,366   0.028382   2.619   0.132925   0.867075 |
     |----------------------------------------------------------------|
 16. |  70   105,169   4,337   0.041238   2.593   0.187573   0.812427 |
 17. |  75    73,694   5,279   0.071634   2.518   0.304102   0.695898 |
 18. |  80    57,512   6,460   0.112324   2.423   0.435548   0.564452 |
 19. |  85    32,248   6,146   0.190585   5.247   1.000000   0.000000 |
     +----------------------------------------------------------------+

. list age lx d L T e

     +-------------------------------------------------------+
     | age        lx        d         L           T        e |
     |-------------------------------------------------------|
  1. |   0   100,000      867    99,192   7,288,901   72.889 |
  2. |   1    99,133      147   396,183   7,189,709   72.526 |
  3. |   5    98,986       76   494,741   6,793,526   68.631 |
  4. |  10    98,910       95   494,375   6,298,785   63.682 |
  5. |  15    98,815      481   492,980   5,804,410   58.740 |
     |-------------------------------------------------------|
  6. |  20    98,334      630   490,106   5,311,431   54.014 |
  7. |  25    97,704      553   487,127   4,821,324   49.346 |
  8. |  30    97,151      659   484,175   4,334,198   44.613 |
  9. |  35    96,492      904   480,384   3,850,023   39.900 |
 10. |  40    95,588    1,393   474,686   3,369,639   35.252 |
     |-------------------------------------------------------|
 11. |  45    94,195    2,258   465,777   2,894,953   30.734 |
 12. |  50    91,937    3,225   452,188   2,429,176   26.422 |
 13. |  55    88,711    4,867   432,096   1,976,988   22.286 |
 14. |  60    83,845    7,467   401,480   1,544,893   18.426 |
 15. |  65    76,377   10,152   357,713   1,143,412   14.971 |
     |-------------------------------------------------------|
 16. |  70    66,225   12,422   301,224     785,699   11.864 |
 17. |  75    53,803   16,362   228,404     484,475    9.005 |
 18. |  80    37,441   16,307   145,182     256,070    6.839 |
 19. |  85    21,134   21,134   110,889     110,889    5.247 |
     +-------------------------------------------------------+

Finally, we will plot a couple of life table functions using the mid-points of the age groups:

. gen am = ( age + age[_n+1] )/2
(1 missing value generated)

. replace am = 90 in -1
(1 real change made)

. line m am, xtitle(age) ytitle("log(m)") yscale(log) ///
>         ylabel(.01 .05 .2) title("Austria, 1992") subtitle(males)

. graph export aultm92.png, replace
(file aultm92.png written in PNG format)

We see the familiar overall shape, albeit without the detail of single-year data.