<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>SpatialStatistics on statistical.systems</title>
    <link>https://statistical.systems/tags/spatialstatistics/</link>
    <description>Recent content in SpatialStatistics on statistical.systems</description>
    <image>
      <url>https://statistical.systems/</url>
      <link>https://statistical.systems/</link>
    </image>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Tue, 01 Sep 2026 00:01:00 -0400</lastBuildDate><atom:link href="https://statistical.systems/tags/spatialstatistics/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Every Candle Still Burns</title>
      <link>https://statistical.systems/essays/every_candle_still_burns/</link>
      <pubDate>Tue, 01 Sep 2026 00:01:00 -0400</pubDate>
      
      <guid>https://statistical.systems/essays/every_candle_still_burns/</guid>
      <description>A goddess won her lover eternal life and forgot to ask for youth. Part one of three: a published study of how many years countries spend in poor health, rebuilt from public data because its code was never released. Most of it held.</description>
      <content:encoded><![CDATA[<p>The goddess of the dawn asks Zeus to let the man she loves live forever, and Zeus agrees. The <em>Homeric Hymn to Aphrodite</em> names what she left out: she &ldquo;thought not in her heart to ask youth for him and to strip him of the slough of deadly age.&rdquo; He is a mortal named Tithonus. She has carried him off to live with her by the streams of Ocean, at the ends of the earth.</p>
<p>So Tithonus goes on living, and he goes on aging. The first gray hairs ripple from his head and his chin, and she keeps away from his bed. She still feeds him ambrosia and dresses him in rich clothing. His limbs, once supple, stiffen until he can no longer move or lift them. Then she lays him in a room and closes the shining doors. &ldquo;There he babbles endlessly, and no more has strength at all.&rdquo; Every morning the dawn goes out into the world, and behind those doors the voice keeps going.</p>
<p>Aphrodite tells this story on the slopes of Mount Ida, to a mortal lover of her own, the herdsman Anchises. Then she refuses him the very gift the dawn once asked for. The goddess of love would not ask for forever without youth.</p>
<p>Picture Tithonus&rsquo;s birthday cake after a few hundred years. Every candle on it still burns. Take out one for every year he could not get out of bed, and almost nothing is left.</p>
<p>No country is Tithonus, but every country has a cake. It carries one candle for every year a baby born there in 2021 can expect to live. One candle comes out for every year&rsquo;s worth of poor health. The years of the bad knee, when the stairs get taken one at a time. The years of the pill organizer, seven plastic lids snapped open every morning.</p>
<p>The cake in Australia carries eighty-three candles. Lit all at once, they throw enough heat that everyone at the table leans back. Twelve and a half come out. The cake in Lesotho carries fifty-one, and almost seven come out. The longer life loses more candles.</p>
<p>Researchers call the pulled candles the healthspan-lifespan gap: life expectancy minus healthy life expectancy. In 2025, a paper in <em>Communications Medicine</em> counted them for 183 countries from 2000 to 2019, using World Health Organization and United Nations data. The global median gap was 9.1 years. Then it asked why the gap is wider in some regions than others.</p>
<p>As lives get longer, the gap grows with them: roughly one pulled candle for every six or seven added. That holds even when a country is compared only with its own past. A headline about living longer rarely mentions that cost. Every year added to a country&rsquo;s average cake comes with nearly two months of the bad knee and the pill organizer. The paper projects the gap to widen 22 percent by 2100, and a baby from the 2021 cakes would be seventy-nine by then.</p>
<p>Counts of healthy years do not stay in journals. In 2017, a review of Britain&rsquo;s pension age gave a full section to how long people stay well, not only how long they live. Insurers that sell long-term care price each policy on how likely a buyer is to need help bathing, dressing, or eating, and for how many years.</p>
<p>A bet on how long one person will live can go badly wrong. In 1965, a notary in Arles named André-François Raffray, forty-seven years old, bought the apartment of a ninety-year-old woman named Jeanne Calment as a <em>viager</em>, a French sale for life. He would pay her 2,500 francs a month until she died, and then the apartment would be his. He paid for thirty years and died first, in December 1995. His widow kept paying. Calment lived to 122, the longest documented life on record. She spent her last twelve years in a nursing home and her last seven in a wheelchair after breaking her femur at 114. By the end she was nearly blind and deaf. Raffray priced how long she would live. Nobody at that table priced how many of those years she would need help to get out of bed. Of the deal, she said only, &ldquo;In life, one sometimes makes bad deals.&rdquo;</p>
<p>Your own plans get built on bets like his: when to retire, how long to save, who will care for whom. Most of them count only the lit candles. A plan to travel at seventy assumes the knee still works at seventy. A promise to look after a parent at home assumes a number of years that nobody wrote down. If the count of healthy years behind a plan is wrong, the time to find out is before the plan comes due.</p>
<p>Anyone at the table can count the candles on a cake, and anyone who doubts the count can count them again. The paper&rsquo;s cakes cannot be counted twice. Every number in it comes from public data. The code that did the counting was never released, so nobody outside the team can check which of its numbers stand up.</p>
<p>So I counted the candles again myself, rebuilding the study from its methods section and its figures alone. Most of it held. I also added one number the paper did not use: how much each country spends on health. Its link to the pulled candles showed up clearly on only some of the cakes. Parts two and three follow the paper further: which diseases pull the candles, and how many more will come out by 2100.</p>
<h2 id="counting-the-candles">Counting the Candles</h2>
<p>I gave myself one rule going in. Rebuild what the public data and the methods section allow, and say so wherever they stop. When a replication has to guess at every missing step, it stops being a replication. It becomes a different study.</p>
<p>The rule was tested almost at once. The gap itself takes two numbers per country, life expectancy and healthy life expectancy, and WHO hands both out through a public data service. The paper&rsquo;s second half needs something harder: how many healthy years each country loses to each disease. That data lives somewhere else, and <a href="/essays/what_lit_the_log/">the count of which diseases pull the candles</a> picks it up.</p>
<p>To compare countries, the paper used only the most recent year in its data, 2019, not the full run of years. I did the same, but WHO now publishes both numbers through 2021, so I used the 2021 instead. Matching 2019 to the decimal was never possible anyway. WHO revises its past estimates as new data comes in, so the 2019 figures the authors downloaded are not the ones WHO serves today.</p>
<p>The paper found two things. Africa had the narrowest gap of the six WHO regions. Life expectancy, GDP, and noncommunicable disease burden were the most consistent predictors of gap size. For 2021 alone, 185 countries in all, here is what I found:</p>
<ul>
<li>Africa&rsquo;s median gap, 8.22 years, is the narrowest of the six regions.</li>
<li>The six regions differ by far more than chance would allow. If the regions did not really differ, a spread this wide would turn up less than once in ten trillion tries (a Kruskal-Wallis test).</li>
<li>Life expectancy alone explains about four-fifths of the country-to-country spread in the gap. The longer a country&rsquo;s people live, the more candles come out.</li>
<li>The paper&rsquo;s other two predictors went untested here. Its economic number was GDP; I used health spending as a share of GDP instead. Together the two explain 82 percent of the spread, against 81 for life expectancy alone. Its third, noncommunicable disease burden, needs the disease data that part two brings in.</li>
</ul>
<p>Some numbers moved. The paper counted 183 countries in 2019, and I counted 185 in 2021. Its global median gap was 9.1 years, and mine is 9.3. It puts Lesotho&rsquo;s gap at 6.5 years, and my count gives 6.84. The finding stays the same: Africa has the narrowest gap, and life expectancy predicts it best.</p>
<p>Two countries have no health-spending figure. Figure 1 uses all 185, and every model after it uses the 183 with a spending figure. That matches the paper&rsquo;s count, but only by coincidence.</p>
<p><strong>Figure 1</strong> shows the same finding three ways.</p>
<p><img loading="lazy" src="/images/012%20-%20fig1a_healthspan_lifespan_density.png" type="" alt="Healthspan versus lifespan distributions by region"  /></p>
<p><em>Figure 1a.</em> Healthspan and lifespan distributions by region, 2021. Teal is lifespan; red is healthspan.</p>
<p>Panel (a) draws each region&rsquo;s two numbers as two hills. The teal hill is how long people live. The red hill is how long they live in good health. Where a hill is taller, more countries sit at that number of years. In every region the red hill sits to the left of the teal one, and the space between them is the pile of pulled candles. Panel (c) ranks the regions by that space. In Europe and South-East Asia each hill has two humps, most likely because each of those regions holds two different kinds of country under one name.</p>
<div class="gap-map" id="gap-map">
  <style>
    .gap-map { margin: 2rem 0 2.5rem; }
    .gap-map {
      --gap-map-nodata: #d8dbe0;
    }
    .dark .gap-map {
      --gap-map-nodata: #3a3f4a;
    }
    .gap-map .gap-map-wrap {
      border: 1px solid var(--border);
      border-radius: var(--radius);
      background: var(--entry);
      padding: 1.2rem 1.2rem 1rem;
      position: relative;
      left: 50%;
      transform: translateX(-50%);
      width: min(940px, 94vw);
    }
    .gap-map .gap-map-caption {
      font-size: 14px;
      font-weight: 600;
      color: var(--primary);
      margin-bottom: 0.6rem;
    }
    .gap-map svg { display: block; width: 100%; height: auto; }
    .gap-map .gap-map-country { stroke: var(--entry); stroke-width: 0.5; cursor: pointer; }
    .gap-map .gap-map-country:hover { stroke: var(--primary); stroke-width: 1; }
    .gap-map .gap-map-country.is-selected { stroke: var(--primary); stroke-width: 1.75; }
    .gap-map .gap-map-detail {
      margin-top: 0.9rem;
      padding: 0.85rem 1rem;
      border: 1px solid var(--border);
      border-radius: var(--radius);
      background: var(--code-bg, var(--main));
      font-size: 13.5px;
      color: var(--secondary);
    }
    .gap-map .gap-map-detail.is-empty { font-style: italic; }
    .gap-map .gap-map-detail-name { font-weight: 600; color: var(--primary); font-size: 14.5px; display: block; margin-bottom: 0.35rem; }
    .gap-map .gap-map-detail-rows { display: flex; flex-wrap: wrap; gap: 0.3rem 1.4rem; }
    .gap-map .gap-map-detail-rows span strong { color: var(--primary); }
    .gap-map .gap-map-legend {
      display: flex;
      align-items: center;
      gap: 0.6rem;
      margin-top: 0.8rem;
      font-size: 13px;
      color: var(--secondary);
    }
    .gap-map .gap-map-legend-bar {
      flex: 1;
      height: 10px;
      border-radius: 5px;
    }
    .gap-map .gap-map-note {
      margin-top: 0.5rem;
      font-size: 12.5px;
      color: var(--secondary);
    }
  </style>

  <div class="gap-map-wrap">
    <div class="gap-map-caption">Healthspan-lifespan gap by country, <span id="gap-map-year">&hellip;</span></div>
    <svg id="gap-map-svg" viewBox="0 0 960 500" preserveAspectRatio="xMidYMid meet" role="img" aria-label="World map colored by the healthspan-lifespan gap"></svg>
    <div class="gap-map-legend">
      <span id="gap-map-min">&nbsp;</span>
      <div class="gap-map-legend-bar" id="gap-map-legend-bar"></div>
      <span id="gap-map-max">&nbsp;</span>
    </div>
    <div class="gap-map-note">Gap = life expectancy minus healthy life expectancy, in years. Click a country for the full breakdown. Gray = no data.</div>
    <div class="gap-map-detail is-empty" id="gap-map-detail">Click a country to see its life expectancy, healthy life expectancy, and the gap between them.</div>
  </div>

  <script src="/js/d3-map-bundle.d5caa7328398b9a59e6407704e87a6c2e94feb6d0aec0756d8cc1f745ed6ce3c.js"></script>
  <script>
  (function () {
    var svg = document.getElementById('gap-map-svg');
    var ns = 'http://www.w3.org/2000/svg';
    var projection = d3.geoNaturalEarth1().scale(155).translate([480, 250]);
    var path = d3.geoPath(projection);

    
    
    var COLOR_STOPS = [
      [0 / 6, [229, 62, 62]],    
      [1 / 6, [249, 115, 22]],   
      [2 / 6, [234, 179, 8]],    
      [3 / 6, [34, 197, 94]],    
      [4 / 6, [59, 130, 246]],   
      [5 / 6, [139, 92, 246]],   
      [6 / 6, [236, 72, 153]]    
    ];
    function colorFor(t) {
      t = Math.max(0, Math.min(1, t));
      for (var i = 0; i < COLOR_STOPS.length - 1; i++) {
        var a = COLOR_STOPS[i], b = COLOR_STOPS[i + 1];
        if (t >= a[0] && t <= b[0]) {
          var u = (t - a[0]) / (b[0] - a[0]);
          var c = [0, 1, 2].map(function (k) { return Math.round(a[1][k] + (b[1][k] - a[1][k]) * u); });
          return 'rgb(' + c.join(',') + ')';
        }
      }
      return 'rgb(220,38,38)';
    }

    Promise.all([
      fetch('\/data\/gapyears\/countries-110m.json').then(function (r) { return r.json(); }),
      fetch('\/data\/gapyears\/fig1-gap-by-country.json').then(function (r) { return r.json(); })
    ]).then(function (res) {
      var topo = res[0], data = res[1];
      var byId = {};
      data.countries.forEach(function (c) { byId[String(c.id)] = c; });
      var gaps = data.countries.map(function (c) { return c.gap; });
      var min = Math.min.apply(null, gaps), max = Math.max.apply(null, gaps);

      document.getElementById('gap-map-year').textContent = data.year;
      document.getElementById('gap-map-min').textContent = min.toFixed(1) + 'y';
      document.getElementById('gap-map-max').textContent = max.toFixed(1) + 'y';
      var gradientStops = COLOR_STOPS.map(function (s) { return colorFor(s[0]) + ' ' + (s[0] * 100) + '%'; }).join(', ');
      document.getElementById('gap-map-legend-bar').style.background = 'linear-gradient(to right, ' + gradientStops + ')';

      var detail = document.getElementById('gap-map-detail');
      var selected = null;

      function showDetail(rec, name) {
        if (!rec) {
          detail.className = 'gap-map-detail is-empty';
          detail.innerHTML = 'No healthspan-lifespan data for ' + name + '.';
          return;
        }
        detail.className = 'gap-map-detail';
        detail.innerHTML =
          '<span class="gap-map-detail-name">' + rec.name + ' (' + rec.region + ')</span>' +
          '<span class="gap-map-detail-rows">' +
          '<span>Life expectancy: <strong>' + rec.life_expectancy.toFixed(1) + 'y</strong></span>' +
          '<span>Healthy life expectancy: <strong>' + rec.healthy_life_expectancy.toFixed(1) + 'y</strong></span>' +
          '<span>Gap: <strong>' + rec.gap.toFixed(1) + 'y</strong></span>' +
          '</span>';
      }

      function clearSelection() {
        if (selected) selected.classList.remove('is-selected');
        selected = null;
        detail.className = 'gap-map-detail is-empty';
        detail.innerHTML = 'Click a country to see its life expectancy, healthy life expectancy, and the gap between them.';
      }

      var features = topojson.feature(topo, topo.objects.countries).features;
      var g = document.createElementNS(ns, 'g');
      svg.appendChild(g);
      features.forEach(function (f) {
        var d = path(f);
        if (!d) return;
        
        
        
        var key = String(parseInt(f.id, 10));
        var rec = byId[key];
        var el = document.createElementNS(ns, 'path');
        el.setAttribute('d', d);
        el.setAttribute('class', 'gap-map-country');
        var name = (f.properties && f.properties.name) || 'This country';
        var titleText = name;
        if (rec) {
          var t = (max === min) ? 0.5 : (rec.gap - min) / (max - min);
          el.setAttribute('fill', colorFor(t));
          titleText = rec.name + ': ' + rec.gap.toFixed(1) + ' years';
        } else {
          el.setAttribute('fill', 'var(--gap-map-nodata)');
        }
        var title = document.createElementNS(ns, 'title');
        title.textContent = titleText;
        el.appendChild(title);
        el.addEventListener('click', function () {
          if (selected === el) { clearSelection(); return; }
          if (selected) selected.classList.remove('is-selected');
          el.classList.add('is-selected');
          selected = el;
          showDetail(rec, name);
        });
        g.appendChild(el);
      });
      svg.addEventListener('click', function (ev) {
        if (ev.target === svg) clearSelection();
      });
    }).catch(function (err) {
      svg.insertAdjacentHTML('afterend', '<p style="color:var(--secondary);font-size:13px;">Map data failed to load.</p>');
      if (window.console) console.error(err);
    });
  })();
  </script>
</div>

<p><em>Figure 1b.</em> Healthspan-lifespan gap by country, 2021. Darker countries have a wider gap.</p>
<p>Panel (b) maps the gap country by country. The darkest countries are Australia, the United States, New Zealand, Switzerland, and France. Four of them have some of the longest lives on earth. The United States is the exception. Its people live six to seven years less than the other four, and it still loses almost as many candles as Australia.</p>
<p><img loading="lazy" src="/images/012%20-%20fig1c_gap_by_region_boxplot.png" type="" alt="Healthspan-lifespan gap by region, boxplot"  /></p>
<p><em>Figure 1c.</em> Healthspan-lifespan gap by region, 2021, ordered from the narrowest median gap to the widest. Each dot is one country.</p>
<p>Panel (c) lines the regions up, from Africa&rsquo;s 8.22-year median on the left to Eastern Mediterranean&rsquo;s 10.22 on the right. The line inside each box marks the typical country, and the box holds the middle half of the region&rsquo;s countries. AFR, AMR, EMR, EUR, SEA, and WP stand for Africa, Americas, Eastern Mediterranean, Europe, South-East Asia, and Western Pacific.</p>
<h2 id="more-candles-than-expected">More Candles Than Expected</h2>
<p>The two numbers from the last section give every country a predicted cake: how many candles it should lose, given how long its people live and how much it spends on health. <strong>Figure 2</strong> sets each real cake beside its prediction.</p>
<p><img loading="lazy" src="/images/012%20-%20fig2a_larger_than_predicted_map.png" type="" alt="Countries with a larger-than-predicted gap"  /></p>
<p><em>Figure 2a.</em> The 94 countries whose gap is larger than their life expectancy and health spending predict, 2021.</p>
<p><img loading="lazy" src="/images/012%20-%20fig2b_smaller_than_predicted_map.png" type="" alt="Countries with a smaller-than-predicted gap"  /></p>
<p><em>Figure 2b.</em> The 89 countries whose gap is smaller than their life expectancy and health spending predict, 2021.</p>
<p><img loading="lazy" src="/images/012%20-%20fig2c_deviation_regional_composition.png" type="" alt="Regional composition of the two deviation groups"  /></p>
<p><em>Figure 2c.</em> Regional makeup of the larger-than-predicted and smaller-than-predicted groups, 2021.</p>
<p>Panel (a) colors in red every country that loses more candles than its prediction. Panel (b) colors in blue every country that loses fewer. Panel (c) turns each group into a ring and slices it by region, so the bigger a slice, the more of that group comes from that region.</p>
<p>Ninety-four countries lose more candles than predicted, and eighty-nine lose fewer. The paper and I found the same region at the top of each group. Africa makes up the biggest share of the countries that lose more: 33 percent in my count, 41 percent in the paper&rsquo;s. Europe makes up the biggest share of the countries that lose fewer: 36 percent in mine, 45 percent in the paper&rsquo;s.</p>
<p>Some of the countries that lose more are the wide-gap countries from the map: the United States, Canada, Australia, the United Kingdom, France, Germany, Italy, and Spain. Their gap is wide, and it is also wider than their own life expectancy and spending predict. China, Japan, and Russia lose fewer than predicted.</p>
<p>The shares do not match exactly, and the two models differ in two ways. The paper&rsquo;s model had a third number, noncommunicable disease burden, and mine does not. Adding it could move some countries from one group to the other. The paper also sorted only some of its countries. Its two groups held 61 and 58, which left 64 of its 183 in neither. I placed every country in one group or the other. So Figure 2 shows what two numbers say, not what the paper&rsquo;s three said.</p>
<h2 id="where-the-spending-link-lives">Where the Spending Link Lives</h2>
<p>So far every comparison has used one year of cakes. Most countries have all twenty-two, 2000 through 2021. The paper does not use them this way, so this section is my own.</p>
<p>Comparing the United States with Somalia shows that countries with longer lives lose more candles. It cannot show whether a country loses more candles in the years its own life expectancy rises. For that, the United States has to be set beside its own cake from five years ago. A fixed-effects panel model makes that comparison. It sets aside everything about a country that stays put, its geography, its history, the baseline quality of its hospitals, and looks only at change within each country.</p>
<p>Life expectancy passes this test almost unchanged. Each added year of life comes with about 0.15 years of added gap, whether countries are compared with each other or each country only with itself. That is where the one pulled candle for every six or seven comes from.</p>
<p>Health spending does not pass as cleanly. It is measured as a share of a country&rsquo;s economy. Across countries, each extra percentage point of GDP spent on health comes with about nineteen more days of gap, about a twentieth of a candle. Compare each cake only with its own past cakes, and that falls to about eight days. The effect shrinks by more than half. Eight days is small, but the data leave no real doubt that it is more than zero. Countries that spend more also differ in other lasting ways, and part of what looked like a spending effect came from those differences. A standard test asks whether those lasting differences are tangled up with life expectancy and spending. It says they are, so the within-country number is the one to trust.</p>
<p>Back to 2021 alone. The regression behind Figure 2 draws one line through all the countries. That line describes the average country. It cannot say whether the countries losing fewer candles than predicted follow the same rule as the countries losing more. Quantile regression checks. Line the cakes up, from the ones that lose the fewest candles for their life expectancy and spending to the ones that lose the most. Quantile regression fits the same two-number model at five points along that line-up: the 10th, 25th, 50th, 75th, and 90th percentiles of the gap.</p>
<p>Life expectancy holds steady at all five, at about 0.16 years of gap for each added year of life. Health spending does not. From the 10th percentile up through the middle, its effect is small, five to nine days, and too uncertain to tell apart from zero. At the 75th and 90th percentiles it turns clear, about twenty days of gap per percentage point. The extra candles that come with spending show up clearly only on the cakes that lose the most for their life expectancy. Those cakes are the top quarter or so, the far end of Figure 2&rsquo;s red group. With 183 countries, the data cannot say for certain that the rest follow a different rule, only that they do not show this one.</p>
<h2 id="what-the-neighbors-share">What the Neighbors Share</h2>
<p>Figure 2 judges every cake on its own, but no cake stands on the table alone. Neighbors often share a climate, diseases, and trade. If that sharing shows up in the gap, some of Figure 2&rsquo;s groups could be partly geography. The paper allows for this with a spatial error model, which adjusts the regression for where each country sits. Before building one, I checked whether it was needed.</p>
<p>Every cake misses its predicted count by some amount. A plain regression treats each country&rsquo;s miss as its own, unrelated to the miss of the country next door. If neighbors tend to miss in the same direction, that assumption is wrong.</p>
<p>Moran&rsquo;s I measures how much neighbors&rsquo; misses resemble each other. To judge it, I shuffled the countries&rsquo; misses across the map 999 times and recomputed it after each shuffle. Only about one shuffle in a hundred came out as extreme as the real map. Neighbors do share their misses.</p>
<p>The paper does not say how it decided which countries count as neighbors, so its spatial model cannot be rebuilt, only one like it. In mine, the closer two countries&rsquo; center points are, the more their misses are allowed to move together. The pull turned out to be real. Take it out, and the model matches the real cakes far worse, by more than chance could explain. The pull fades with distance, down to about a third of its strength by roughly 1,200 to 1,900 km apart. Life expectancy and spending both still matter after the adjustment, with spending at about fourteen days of gap per percentage point.</p>
<p><strong>Figure 2d</strong> puts panels (a) and (b) on one map. A switch on the map flips between the plain view and the view adjusted for neighbors. The red of panel (a) turns orange here: orange countries lose more candles than predicted, and blue countries lose fewer. The ringed countries are the ones that change groups between the two views.</p>
<div class="spatial-map" id="spatial-map">
  <style>
    .spatial-map { margin: 2rem 0 2.5rem; }
    .spatial-map {
      --spatial-larger: #f97316;
      --spatial-smaller: #3b82f6;
      --spatial-nodata: #d8dbe0;
      --spatial-flip-ring: #111827;
    }
    .dark .spatial-map {
      --spatial-nodata: #3a3f4a;
      --spatial-flip-ring: #f5f5f5;
    }
    .spatial-map .spatial-map-wrap {
      border: 1px solid var(--border);
      border-radius: var(--radius);
      background: var(--entry);
      padding: 1.2rem 1.2rem 1rem;
      position: relative;
      left: 50%;
      transform: translateX(-50%);
      width: min(940px, 94vw);
    }
    .spatial-map .spatial-map-head {
      display: flex;
      align-items: baseline;
      justify-content: space-between;
      flex-wrap: wrap;
      gap: 0.6rem;
      margin-bottom: 0.7rem;
    }
    .spatial-map .spatial-map-caption { font-size: 14px; font-weight: 600; color: var(--primary); }
    .spatial-map .spatial-map-toggle {
      display: inline-flex;
      border: 1px solid var(--border);
      border-radius: 999px;
      overflow: hidden;
      font-size: 12.5px;
    }
    .spatial-map .spatial-map-toggle button {
      appearance: none;
      border: none;
      background: transparent;
      color: var(--secondary);
      padding: 0.32rem 0.85rem;
      cursor: pointer;
      font: inherit;
    }
    .spatial-map .spatial-map-toggle button.is-active {
      background: var(--primary);
      color: var(--entry);
      font-weight: 600;
    }
    .spatial-map svg { display: block; width: 100%; height: auto; }
    .spatial-map .spatial-map-country { stroke: var(--entry); stroke-width: 0.5; cursor: pointer; transition: fill 0.25s ease; }
    .spatial-map .spatial-map-country:hover { stroke: var(--primary); stroke-width: 1; }
    .spatial-map .spatial-map-country.is-selected { stroke: var(--primary); stroke-width: 1.75; }
    .spatial-map .spatial-map-flip { fill: none; stroke: var(--spatial-flip-ring); stroke-width: 1.4; pointer-events: none; }
    .spatial-map .spatial-map-legend {
      display: flex;
      flex-wrap: wrap;
      gap: 1.1rem;
      margin-top: 0.8rem;
      font-size: 12.5px;
      color: var(--secondary);
      align-items: center;
    }
    .spatial-map .spatial-map-legend span { display: inline-flex; align-items: center; gap: 0.4rem; }
    .spatial-map .spatial-map-swatch { width: 12px; height: 12px; border-radius: 3px; display: inline-block; }
    .spatial-map .spatial-map-flip-swatch {
      width: 12px; height: 12px; border-radius: 50%;
      border: 1.4px solid var(--spatial-flip-ring);
      display: inline-block;
    }
    .spatial-map .spatial-map-note { margin-top: 0.5rem; font-size: 12.5px; color: var(--secondary); }
    .spatial-map .spatial-map-detail {
      margin-top: 0.9rem;
      padding: 0.85rem 1rem;
      border: 1px solid var(--border);
      border-radius: var(--radius);
      background: var(--code-bg, var(--main));
      font-size: 13.5px;
      color: var(--secondary);
    }
    .spatial-map .spatial-map-detail.is-empty { font-style: italic; }
    .spatial-map .spatial-map-detail-name { font-weight: 600; color: var(--primary); font-size: 14.5px; display: block; margin-bottom: 0.35rem; }
    .spatial-map .spatial-map-detail-rows { display: flex; flex-direction: column; gap: 0.2rem; }
    .spatial-map .spatial-map-detail-rows span strong { color: var(--primary); }
    .spatial-map .spatial-map-flip-tag {
      display: inline-block;
      margin-top: 0.4rem;
      font-size: 12px;
      font-weight: 600;
      color: var(--primary);
    }
  </style>

  <div class="spatial-map-wrap">
    <div class="spatial-map-head">
      <div class="spatial-map-caption">Gap deviation, plain regression vs. spatial-adjusted, <span id="spatial-map-year">&hellip;</span></div>
      <div class="spatial-map-toggle" role="group" aria-label="Model">
        <button type="button" id="spatial-map-btn-ols" class="is-active">Plain regression</button>
        <button type="button" id="spatial-map-btn-gls">Spatial-adjusted</button>
      </div>
    </div>
    <svg id="spatial-map-svg" viewBox="0 0 960 500" preserveAspectRatio="xMidYMid meet" role="img" aria-label="World map colored by whether a country's healthspan-lifespan gap is larger or smaller than the regression predicts"></svg>
    <div class="spatial-map-legend">
      <span><span class="spatial-map-swatch" style="background:var(--spatial-larger)"></span>Larger than predicted</span>
      <span><span class="spatial-map-swatch" style="background:var(--spatial-smaller)"></span>Smaller than predicted</span>
      <span><span class="spatial-map-flip-swatch"></span>Flips between the two models</span>
    </div>
    <div class="spatial-map-note">"Predicted" = this repo's own gap ~ life expectancy + health spending regression. The spatial-adjusted view lets nearby countries' residuals correlate instead of treating each country as independent. Click a country for both classifications; ringed countries are the ones that disagree.</div>
    <div class="spatial-map-detail is-empty" id="spatial-map-detail">Click a country to compare its plain-regression and spatial-adjusted classification.</div>
  </div>

  <script src="/js/d3-map-bundle.d5caa7328398b9a59e6407704e87a6c2e94feb6d0aec0756d8cc1f745ed6ce3c.js"></script>
  <script>
  (function () {
    var svg = document.getElementById('spatial-map-svg');
    var ns = 'http://www.w3.org/2000/svg';
    var projection = d3.geoNaturalEarth1().scale(155).translate([480, 250]);
    var path = d3.geoPath(projection);
    var COLORS = {
      'Larger than predicted': 'var(--spatial-larger)',
      'Smaller than predicted': 'var(--spatial-smaller)'
    };

    var mode = 'ols'; 
    var byId = {};
    var countryEls = {};   
    var flipRings = [];    
    var selected = null;
    var detail = document.getElementById('spatial-map-detail');
    var btnOls = document.getElementById('spatial-map-btn-ols');
    var btnGls = document.getElementById('spatial-map-btn-gls');

    function deviationField() { return mode === 'ols' ? 'ols_deviation' : 'gls_deviation'; }
    function residualField() { return mode === 'ols' ? 'ols_residual' : 'gls_residual'; }

    function repaint() {
      Object.keys(countryEls).forEach(function (id) {
        var rec = byId[id];
        var el = countryEls[id];
        if (!rec) { el.setAttribute('fill', 'var(--spatial-nodata)'); return; }
        el.setAttribute('fill', COLORS[rec[deviationField()]] || 'var(--spatial-nodata)');
      });
      if (selected) {
        var rec = byId[selected.dataset.id];
        if (rec) showDetail(rec);
      }
    }

    function showDetail(rec) {
      detail.className = 'spatial-map-detail';
      detail.innerHTML =
        '<span class="spatial-map-detail-name">' + rec.name + ' (' + rec.region + ')</span>' +
        '<span class="spatial-map-detail-rows">' +
        '<span>Plain regression: <strong>' + rec.ols_deviation + '</strong> (residual ' + (rec.ols_residual > 0 ? '+' : '') + rec.ols_residual.toFixed(2) + ')</span>' +
        '<span>Spatial-adjusted: <strong>' + rec.gls_deviation + '</strong> (residual ' + (rec.gls_residual > 0 ? '+' : '') + rec.gls_residual.toFixed(2) + ')</span>' +
        '</span>' +
        (rec.flipped ? '<span class="spatial-map-flip-tag">Flips once geography is accounted for</span>' : '');
    }

    function clearSelection() {
      if (selected) selected.classList.remove('is-selected');
      selected = null;
      detail.className = 'spatial-map-detail is-empty';
      detail.innerHTML = 'Click a country to compare its plain-regression and spatial-adjusted classification.';
    }

    btnOls.addEventListener('click', function () {
      if (mode === 'ols') return;
      mode = 'ols'; btnOls.classList.add('is-active'); btnGls.classList.remove('is-active'); repaint();
    });
    btnGls.addEventListener('click', function () {
      if (mode === 'gls') return;
      mode = 'gls'; btnGls.classList.add('is-active'); btnOls.classList.remove('is-active'); repaint();
    });

    Promise.all([
      fetch('\/data\/gapyears\/countries-110m.json').then(function (r) { return r.json(); }),
      fetch('\/data\/gapyears\/fig2d-spatial-deviation.json').then(function (r) { return r.json(); })
    ]).then(function (res) {
      var topo = res[0], data = res[1];
      data.countries.forEach(function (c) { byId[String(c.id)] = c; });
      document.getElementById('spatial-map-year').textContent = data.year;

      var features = topojson.feature(topo, topo.objects.countries).features;
      var g = document.createElementNS(ns, 'g');
      svg.appendChild(g);
      var flipsG = document.createElementNS(ns, 'g');

      features.forEach(function (f) {
        var d = path(f);
        if (!d) return;
        var key = String(parseInt(f.id, 10));
        var rec = byId[key];
        var el = document.createElementNS(ns, 'path');
        el.setAttribute('d', d);
        el.setAttribute('class', 'spatial-map-country');
        el.dataset.id = key;
        var name = (f.properties && f.properties.name) || 'This country';
        el.setAttribute('fill', rec ? COLORS[rec[deviationField()]] : 'var(--spatial-nodata)');
        var title = document.createElementNS(ns, 'title');
        title.textContent = rec ? (rec.name + ': ' + rec[deviationField()]) : name;
        el.appendChild(title);
        el.addEventListener('click', function () {
          if (!rec) return;
          if (selected === el) { clearSelection(); return; }
          if (selected) selected.classList.remove('is-selected');
          el.classList.add('is-selected');
          selected = el;
          showDetail(rec);
        });
        g.appendChild(el);
        countryEls[key] = el;

        if (rec && rec.flipped) {
          var pt = projection([rec.lon, rec.lat]);
          if (pt) {
            var ring = document.createElementNS(ns, 'circle');
            ring.setAttribute('cx', pt[0]);
            ring.setAttribute('cy', pt[1]);
            ring.setAttribute('r', 4.5);
            ring.setAttribute('class', 'spatial-map-flip');
            flipsG.appendChild(ring);
          }
        }
      });
      svg.appendChild(flipsG);
    }).catch(function (err) {
      svg.insertAdjacentHTML('afterend', '<p style="color:var(--secondary);font-size:13px;">Map data failed to load.</p>');
      if (window.console) console.error(err);
    });

    svg.addEventListener('click', function (ev) {
      if (ev.target === svg) clearSelection();
    });
  })();
  </script>
</div>

<p><em>Figure 2d.</em> Gap against prediction, 2021, from the plain regression and from the model adjusted for neighboring countries (spatial error model). Orange is larger than predicted; blue is smaller.</p>
<p>Eight of the 183 countries change groups. Five are in Europe: Austria, Cyprus, Czechia, Denmark, and the Netherlands. All five move from fewer candles than predicted to more. The other three, Zimbabwe, Saint Lucia, and Somalia, move the opposite way. None of the eight moved far. Before the adjustment, each one sat within about a month of its prediction, a twelfth of a candle, right on the line between the groups. A spatial model pulls neighbors&rsquo; misses toward each other by design. A few borderline European countries tipping over together is the kind of change it is built to make.</p>
<p>What holds is the regional pattern. After the adjustment, Africa still makes up the biggest share of the countries that lose more candles, at 31 percent. Europe still makes up the biggest share of the countries that lose fewer, also at 31 percent. The paper reports the same pattern holding under its own adjustment.</p>
<blockquote>
<p><strong>A Closing Reflection</strong>. <em>Every candle on Tithonus&rsquo;s cake still burns. Counting the lit ones was never the hard part. The hard part is the ones that come out, and a single average will not say which ones those are, or whose.</em></p>
<ol>
<li>An older person you know well, and the first year you remember them taking the stairs one at a time. Not the birthday with the big number on it. The year the railing started doing some of the work.</li>
<li>Something in your own mornings that runs a little slower than it used to, a stiff first step out of bed, reading glasses pushed up and then hunted for, and whether you have ever counted it as time at all.</li>
<li>A number you repeat about your family or your hometown, how long people live there, how old your grandmother got, and how it would sound with the healthy years said out loud beside it.</li>
</ol>
<p><em>The goddess of the dawn asked for forever and got it, every candle lit. What she forgot to ask for was the part the flames do not show. The next time someone tells you how long a person lived, notice the small pause before anyone asks how long they were well. Nobody at Raffray&rsquo;s table ever paused there. That pause is where the pulled candles hide. A real birthday cake never takes one out. They show instead in who at the table can still lean in and blow.</em></p></blockquote>
<h2 id="where-this-came-from">Where This Came From</h2>
<p>The study replicated here is Garmany and Terzic (2025), in <em>Communications Medicine</em>. It covers 183 WHO member states from 2000 to 2019. The 9.1-year global median, the findings on regions and predictors, and the 22 percent projection to 2100 are the paper&rsquo;s own. So are the paper&rsquo;s figures set beside mine in the body: its 183 countries in 2019, Lesotho&rsquo;s 6.5 years, the 41 and 45 percent shares, and its groups of 61 and 58. Every other number in this piece comes from my own pipeline, run on WHO Global Health Observatory data pulled on 28 August 2026: life expectancy at birth, healthy life expectancy at birth, and current health expenditure as a share of GDP, for 2000 through 2021. WHO revises its historical estimates, so the paper&rsquo;s figures and mine will not agree to the decimal even where they overlap.</p>
<p>The paper&rsquo;s data is public and its code is not, so the whole replication is rebuilt from the methods section and the published figures. The regional comparison, the two-variable regression, and the residual maps follow the paper&rsquo;s design as closely as the methods text allows. The panel model, the quantile regression, and the Moran&rsquo;s I check are my own additions, not things the paper does. The spatial model is built like the paper&rsquo;s but uses a correlation structure I chose, because the paper does not describe its own. Distance in my model is measured in degrees of latitude and longitude, so its reach runs shorter east to west than north to south. The standard R packages for spatial error models would not build on my setup, so I fit mine with generalized least squares: the same idea, with different tools. The code, the data pulls, the R packages behind each step, and the list of what worked and what did not are public at <a href="https://github.com/gauranii/GapYears">github.com/gauranii/GapYears</a>.</p>
<p>The quoted lines and the details of Tithonus&rsquo;s aging (the gray hairs, the ambrosia and rich clothing, the shining doors) come from the <em>Homeric Hymn to Aphrodite</em>, the oldest surviving version of the story, in Hugh G. Evelyn-White&rsquo;s 1914 translation, lines 218 to 238. The goddess is Eos in that telling. The frame around it comes from the same hymn: Aphrodite on Ida with Anchises, a cattle herder, and her refusal right after the Tithonus story to give him the gift the dawn asked for.</p>
<p>The pension review is John Cridland&rsquo;s <em>Independent Review of the State Pension Age</em> (2017), whose recommendation to raise the age from 67 to 68 starting in 2037 the government accepted that July. That rise has not been legislated. In 2023 the decision was put off to a further review, and a third review began in July 2025. Its section on healthy life expectancy begins on page 34. The insurance pricing comes from the actuarial standard for long-term care in the United States, ASOP No. 18, which asks actuaries to set how often claims begin and how long they last, with benefits triggered by trouble with daily activities such as bathing and dressing, or by cognitive impairment.</p>
<p>The Calment details come from her <em>New York Times</em> obituary (1997): the 1965 <em>viager</em> with Raffray, the 2,500 francs a month, his death in December 1995, and her line about bad deals. Her years in the nursing home, the broken femur at 114, and her near blindness and deafness at the end come from the validation study of her age by Robine and colleagues (2019). Raffray&rsquo;s age in 1965 comes from French accounts of the sale.</p>
<p>The third predictor missing from Figure 2&rsquo;s model is the disease-burden data. It gets its own treatment in part two of this series, <a href="/essays/what_lit_the_log/">a count of which diseases take each country&rsquo;s healthy years</a>, along with the clustering the paper builds on top of it. The 22 percent projection to 2100 is taken up in part three, <a href="/essays/less_than_zero_seconds/">the paper&rsquo;s forecast set against three simpler ones</a>.</p>
<p><strong>Intellectual Honesty Note.</strong> The birthday cake is this piece&rsquo;s own device, not the paper&rsquo;s. The candle counts are the 2021 life expectancy and gap figures, rounded into candles. The dawn going out each morning while his voice keeps going is this piece&rsquo;s own image. The <em>Hymn</em> says only that he babbles endlessly behind the doors. The line that the goddess of love would not ask for forever without youth is this piece&rsquo;s reading of her refusal, not her words. Calment&rsquo;s age was challenged in 2018 by researchers who argued her daughter had taken her identity. The French team that validated her age answered in 2019, and most researchers still accept 122. The bad knee and the pill organizer are illustrations, not anyone&rsquo;s case history. No figure here reproduces one of the paper&rsquo;s figures directly. Each is redrawn from my own numbers, and where my method differs from the paper&rsquo;s, the text says so.</p>
<h2 id="references">References</h2>
<p>Actuarial Standards Board. (2022). <em>Actuarial Standard of Practice No. 18: Long-Term Care</em> (Doc. No. 206).</p>
<p>Cridland, J. (2017). <em>Independent Review of the State Pension Age: Smoothing the Transition</em> (Final report). Department for Work and Pensions.</p>
<p>Evelyn-White, H. G. (Trans.). (1914). <em>Hesiod, the Homeric Hymns, and Homerica</em>. William Heinemann.</p>
<p>Garmany, A., &amp; Terzic, A. (2025). Healthspan-lifespan gap differs in magnitude and disease contribution across world regions. <em>Communications Medicine</em>, 5, 381.</p>
<p>Gauran, I. I. (2026). <em>GapYears</em> (Version 1.0.0) [Computer software]. GitHub. <a href="https://github.com/gauranii/GapYears">https://github.com/gauranii/GapYears</a></p>
<p>Hausman, J. A. (1978). Specification Tests in Econometrics. <em>Econometrica</em>, 46(6), 1251-1271.</p>
<p>Koenker, R., &amp; Bassett, G. (1978). Regression Quantiles. <em>Econometrica</em>, 46(1), 33-50.</p>
<p>Kruskal, W. H., &amp; Wallis, W. A. (1952). Use of Ranks in One-Criterion Variance Analysis. <em>Journal of the American Statistical Association</em>, 47(260), 583-621.</p>
<p>Moran, P. A. P. (1950). Notes on Continuous Stochastic Phenomena. <em>Biometrika</em>, 37(1-2), 17-23.</p>
<p>Robine, J.-M., Allard, M., Herrmann, F. R., &amp; Jeune, B. (2019). The Real Facts Supporting Jeanne Calment as the Oldest Ever Human. <em>The Journals of Gerontology: Series A</em>, 74(Suppl. 1), S13-S20.</p>
<p>Whitney, C. R. (1997, August 5). Jeanne Calment, World&rsquo;s Elder, Dies at 122. <em>The New York Times</em>.</p>
<p>World Health Organization. (n.d.). <em>Global Health Observatory data repository</em> [Data set]. Retrieved August 28, 2026, from <a href="https://www.who.int/data/gho">https://www.who.int/data/gho</a></p>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
