<?xml version="1.0" encoding="UTF-8"?>
<rss  xmlns:atom="http://www.w3.org/2005/Atom" 
      xmlns:media="http://search.yahoo.com/mrss/" 
      xmlns:content="http://purl.org/rss/1.0/modules/content/" 
      xmlns:dc="http://purl.org/dc/elements/1.1/" 
      version="2.0">
<channel>
<title>Peter Kirwan</title>
<link>https://www.pkirwan.com/</link>
<atom:link href="https://www.pkirwan.com/index.xml" rel="self" type="application/rss+xml"/>
<description>Postdoctoral research fellow at the Barcelona Institute for Global Health (ISGlobal). Statistical modelling of infectious disease burden, and a blog series on statistical methods for infectious disease data.</description>
<generator>quarto-1.10.19</generator>
<lastBuildDate>Tue, 23 Dec 2025 00:00:00 GMT</lastBuildDate>
<item>
  <title>Part VIII: Study designs and biases</title>
  <dc:creator>Peter Kirwan</dc:creator>
  <link>https://www.pkirwan.com/blog/study-designs/</link>
  <description><![CDATA[ 






<p>This is part eight of a series on statistical methods for infectious disease epidemiology, with a focus on time-to-event, or “survival”, data.</p>
<p>In this final post of this series I’ll describe a number of observational study designs and several potential sources of bias common to these studies.</p>
<section id="observational-study-designs" class="level2">
<h2 class="anchored" data-anchor-id="observational-study-designs">Observational study designs</h2>
<p>Observational studies are common in epidemiology and a valuable resource for understanding infectious disease burden. Several different types of observational study design exist, which may be more or less suitable depending on the research question, the need to control for specific biases, and the feasibility of data collection.</p>
<div class="cell">
<div class="cell-output-display">
<div id="fig-study-designs" class="quarto-float quarto-figure quarto-figure-center anchored" alt="Pyramid of study designs, from case series and expert opinion at the base, then cross-sectional studies, case-control studies, cohort studies, trials, and systematic reviews and meta-analyses at the top, with an arrow indicating better quality evidence towards the top.">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-study-designs-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://www.pkirwan.com/blog/study-designs/index_files/figure-html/fig-study-designs-1.png" class="img-fluid figure-img" alt="Pyramid of study designs, from case series and expert opinion at the base, then cross-sectional studies, case-control studies, cohort studies, trials, and systematic reviews and meta-analyses at the top, with an arrow indicating better quality evidence towards the top." width="480">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-study-designs-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;1: A hierarchy of different types of study designs and the perceived quality of the evidence. Adapted from: Bodicoat D.
</figcaption>
</figure>
</div>
</div>
</div>
<p>Table&nbsp;1 shows a <img src="https://latex.codecogs.com/png.latex?2%20%5Ctimes%202"> table which may be used to group participants in observational studies and to inform the calculation of standard statistical measures.</p>
<div id="tbl-two-by-two" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-tbl figure">
<figcaption class="quarto-float-caption-top quarto-float-caption quarto-float-tbl" id="tbl-two-by-two-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Table&nbsp;1: A <img src="https://latex.codecogs.com/png.latex?2%20%5Ctimes%202"> table of outcomes and exposures.
</figcaption>
<div aria-describedby="tbl-two-by-two-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<table class="caption-top table">
<thead>
<tr class="header">
<th></th>
<th></th>
<th style="text-align: center;"><strong>Outcome: Yes</strong></th>
<th style="text-align: center;"><strong>Outcome: No</strong></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><strong>Exposure</strong></td>
<td><strong>Yes</strong></td>
<td style="text-align: center;"><img src="https://latex.codecogs.com/png.latex?A"></td>
<td style="text-align: center;"><img src="https://latex.codecogs.com/png.latex?B"></td>
</tr>
<tr class="even">
<td></td>
<td><strong>No</strong></td>
<td style="text-align: center;"><img src="https://latex.codecogs.com/png.latex?C"></td>
<td style="text-align: center;"><img src="https://latex.codecogs.com/png.latex?D"></td>
</tr>
</tbody>
</table>
</div>
</figure>
</div>
<section id="cross-sectional-studies" class="level3">
<h3 class="anchored" data-anchor-id="cross-sectional-studies">Cross-sectional studies</h3>
<p>Cross-sectional studies may be used to assess:</p>
<ul>
<li>the <em>prevalence of an outcome</em>, defined as: <img src="https://latex.codecogs.com/png.latex?(A+C)/(A+B+C+D)"></li>
<li>the <em>prevalence of various different exposures</em>, defined as: <img src="https://latex.codecogs.com/png.latex?(A+B)/(A+B+C+D)"></li>
</ul>
<p>within a population. They provide a snapshot of the population at a single point in time and can be relatively straightforward to conduct using surveillance data.</p>
</section>
<section id="case-control-studies" class="level3">
<h3 class="anchored" data-anchor-id="case-control-studies">Case-control studies</h3>
<p>Case-control studies are used to investigate the effects of specific exposures on an outcome. In these studies the outcome of interest has already occurred, individuals who have experienced the outcome are termed “cases”, and are compared to individuals without the outcome, known as “controls”. The odds of being exposed are compared in cases vs.&nbsp;controls via the <em>odds ratio</em>: <img src="https://latex.codecogs.com/png.latex?%5Cfrac%7BAD%7D%7BBC%7D"></p>
</section>
<section id="test-negative-case-control-studies" class="level3">
<h3 class="anchored" data-anchor-id="test-negative-case-control-studies">Test-negative case-control studies</h3>
<p>Test-negative case-control studies are a sub-type of case-control study, commonly used to estimate vaccine effectiveness. These studies aim to minimise bias specifically as a result of test-seeking behaviour by selecting only individuals who test for a disease. As for case-control studies, the cases are individuals who test positive, controls are those who test negative, and again the odds of being exposed are compared between cases and controls. Since individuals are only included if they were tested, the design implicitly conditions on testing, so it remains important to consider whether the factors that lead to testing could differ between exposure groups (see collider bias below).</p>
</section>
<section id="cohort-studies" class="level3">
<h3 class="anchored" data-anchor-id="cohort-studies">Cohort studies</h3>
<p>In cohort studies participants are selected based on their exposure status and followed up over time, either prospectively or retrospectively using existing records. The incidence of the outcome of interest is compared between individuals with and without the exposure using the <em>relative risk</em>:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Cfrac%7BA/(A+B)%7D%7BC/(C+D)%7D%0A"></p>
</section>
<section id="r-example-two" class="level3">
<h3 class="anchored" data-anchor-id="r-example-two">R example</h3>
<p>The same <img src="https://latex.codecogs.com/png.latex?2%20%5Ctimes%202"> table can therefore support different summaries depending on the study design. The code below shows how to compute the prevalence of the outcome and exposure, the odds ratio, and the relative risk from a <img src="https://latex.codecogs.com/png.latex?2%20%5Ctimes%202"> table in R.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" data-lst-cap="Computing common epidemiological measures from a 2 x 2 table in R." style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb1-1">study_table <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">matrix</span>(</span>
<span id="cb1-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">158</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">28</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">272</span>),</span>
<span id="cb1-3">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">nrow =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>,</span>
<span id="cb1-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">byrow =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>,</span>
<span id="cb1-5">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dimnames =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">list</span>(</span>
<span id="cb1-6">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Exposure =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Yes"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"No"</span>),</span>
<span id="cb1-7">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Outcome =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Yes"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"No"</span>)</span>
<span id="cb1-8">  )</span>
<span id="cb1-9">)</span>
<span id="cb1-10"></span>
<span id="cb1-11">A <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> study_table[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Yes"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Yes"</span>]</span>
<span id="cb1-12">B <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> study_table[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Yes"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"No"</span>]</span>
<span id="cb1-13">C <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> study_table[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"No"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Yes"</span>]</span>
<span id="cb1-14">D <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> study_table[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"No"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"No"</span>]</span>
<span id="cb1-15"></span>
<span id="cb1-16">study_table</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>        Outcome
Exposure Yes  No
     Yes  42 158
     No   28 272</code></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" data-lst-cap="Computing common epidemiological measures from a 2 x 2 table in R." style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb3-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(</span>
<span id="cb3-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(</span>
<span id="cb3-3">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">prevalence_outcome =</span> (A <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> C) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> (A <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> B <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> C <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> D),</span>
<span id="cb3-4">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">prevalence_exposure =</span> (A <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> B) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> (A <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> B <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> C <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> D),</span>
<span id="cb3-5">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">odds_ratio =</span> (A <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> D) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> (B <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> C),</span>
<span id="cb3-6">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">relative_risk =</span> (A <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> (A <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> B)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> (C <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> (C <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> D))</span>
<span id="cb3-7">  ),</span>
<span id="cb3-8">  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span></span>
<span id="cb3-9">)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code> prevalence_outcome prevalence_exposure          odds_ratio       relative_risk 
              0.140               0.400               2.582               2.250 </code></pre>
</div>
</div>
<p>The same four cell counts therefore answer different questions: prevalence in cross-sectional studies, odds ratios in case-control studies, and risks or risk ratios in cohort studies. Not every measure is valid for every design. For example, in a case-control study the numbers of cases and controls are fixed by the study design, so the prevalence of the outcome and the relative risk cannot be estimated directly from the table, whereas the odds ratio can.</p>
</section>
</section>
<section id="biases-in-observational-studies" class="level2">
<h2 class="anchored" data-anchor-id="biases-in-observational-studies">Biases in observational studies</h2>
<p>Bias can be defined as: <em>any process at any stage of inference which tends to produce results or conclusions that differ systematically from the truth</em>. All of the observational study designs described above can include potential sources of bias, which are often grouped into three broad types: information bias, collider bias, and confounding.</p>
<section id="information-bias" class="level3">
<h3 class="anchored" data-anchor-id="information-bias">Information bias</h3>
<p>Information, or measurement, bias arises due to inaccuracies in data and may be induced by errors or missing information in either the outcome or exposure variables, for example, incorrect coding of a diagnosis. Information bias can be mitigated through careful study design and data collection mechanisms, these could include: double entry of data, and linking information across different systems for validation.</p>
</section>
<section id="collider-bias" class="level3">
<h3 class="anchored" data-anchor-id="collider-bias">Collider bias</h3>
<p>Collider bias, a common form of selection bias, occurs when individuals are selected into an analysis by conditioning on a common “collider” variable (a variable which is influenced by two other variables).</p>
<p>Figure&nbsp;2 shows an example of collider bias: people who are regular smokers and people at high risk of severe COVID-19 illness are both more likely to be admitted to hospital. By conditioning on hospitalisation a distorted association between smoking and COVID-19 mortality could be induced, and this bias may occur in either a positive or negative direction. For example: a negative association between smoking and COVID-19 severity was reported by more than one early risk-factor study for COVID-19, with a review concluding this result may have been a result of collider bias.</p>
<div id="fig-collider-bias" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-collider-bias-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell">
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.pkirwan.com/blog/study-designs/index_files/figure-html/unnamed-chunk-2-1.png" class="img-fluid figure-img" alt="Causal diagram with arrows from Regular smoker and from COVID-19 severity to Hospitalisation, which is enclosed in a box. A dashed line without arrowheads joins Regular smoker and COVID-19 severity." width="384"></p>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-collider-bias-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;2: Causal diagram showing the effect of collider bias, where conditioning on hospitalisation induces a distorted association between smoking and COVID-19 severity. Conditioned on variables have bounding boxes, distorted associations are shown as dashed lines.
</figcaption>
</figure>
</div>
<p>Collider bias is most easily avoided by not conditioning on the collider, but this may be impractical depending on the nature of data collection. In the context of COVID-19, Griffith <em>et al.</em> have suggested several methods for assessing the sensitivity of model results to collider bias, such as inverse probability weighting. Where information is available, the extent of the bias can also be examined by comparing the profile of selected individuals to the wider population of interest, e.g.&nbsp;whether hospitalised individuals tend to be older or more likely to have comorbidities as compared to the general population.</p>
</section>
<section id="confounding" class="level3">
<h3 class="anchored" data-anchor-id="confounding">Confounding</h3>
<p>Confounding is related to collider bias, but occurs by not conditioning on an explanatory variable. Confounding introduces a “backdoor path”, an additional source of association between the explanatory variable and the outcome, so the measured association cannot be interpreted as a causal effect.</p>
<p>An example of confounding is shown in the causal diagram in Figure&nbsp;3: during vaccine roll-out older people were more likely to receive a COVID-19 vaccine, but also more likely to experience severe COVID-19. If age group is not adjusted for then a distorted association between vaccination and COVID-19 severity may be induced. Confounding can be avoided by ensuring that factors that might be associated with the outcome are measured and adjusted for.</p>
<div id="fig-confounding" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-confounding-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell">
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.pkirwan.com/blog/study-designs/index_files/figure-html/unnamed-chunk-3-1.png" class="img-fluid figure-img" alt="Causal diagram with arrows from Age group to COVID-19 severity and to Vaccination. A dashed line without arrowheads joins COVID-19 severity and Vaccination." width="384"></p>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-confounding-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;3: Causal diagram showing the effect of confounding, where not conditioning on age group induces a distorted association between vaccination and COVID-19 severity. Distorted associations are shown as dashed lines.
</figcaption>
</figure>
</div>
</section>
<section id="epidemic-phase-bias" class="level3">
<h3 class="anchored" data-anchor-id="epidemic-phase-bias">Epidemic phase bias</h3>
<p>Epidemic phase bias occurs in studies with time-varying incidence of infection. This bias is induced by a relationship between the time from infection to symptom onset and an individual’s eventual outcome, e.g.&nbsp;those who go on to die may experience a more rapid onset of symptoms following infection, an average of <img src="https://latex.codecogs.com/png.latex?c"> days sooner. Since estimates must be conditioned on the observed symptom onset date, rather than the unobserved infection date, this relationship can introduce bias into results when an epidemic is in a mode of growth or decline.</p>
<p>Epidemic phase bias is corrected by “shifting” the symptom onset date among those who experience the more severe outcome to be <img src="https://latex.codecogs.com/png.latex?c"> days later, so that the time from infection to symptom onset is uncorrelated with the outcome (the time-to-event of interest remains the same for both outcomes.) As the true value of <img src="https://latex.codecogs.com/png.latex?c"> is typically unknown, sensitivity analysis with differing values of <img src="https://latex.codecogs.com/png.latex?c"> can be used to assess the susceptibility of results to this bias.</p>
</section>
<section id="r-example-epidemic-phase-bias" class="level3">
<h3 class="anchored" data-anchor-id="r-example-epidemic-phase-bias">R example</h3>
<p>The simple sensitivity analysis below shows the basic mechanism in a growing epidemic where severe outcomes are associated with faster symptom onset.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb5" data-lst-cap="Sensitivity analysis for epidemic phase bias in R." style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb5-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">set.seed</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2026</span>)</span>
<span id="cb5-2"></span>
<span id="cb5-3">n             <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1000</span></span>
<span id="cb5-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Growing epidemic: infections concentrated on later days</span></span>
<span id="cb5-5">infection_day <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sample</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">30</span>, n, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">replace =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">prob =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">30</span>)</span>
<span id="cb5-6">severe        <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rbinom</span>(n, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.15</span>)</span>
<span id="cb5-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Severe cases present 3 days faster than mild cases</span></span>
<span id="cb5-8">onset_day     <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> infection_day <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ifelse</span>(severe <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>)</span>
<span id="cb5-9"></span>
<span id="cb5-10"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Sensitivity analysis: shift the severe-case onset date by c days</span></span>
<span id="cb5-11">cutoff <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">30</span></span>
<span id="cb5-12">epb_df <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">data.frame</span>(</span>
<span id="cb5-13">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">shift_days     =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>,</span>
<span id="cb5-14">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">estimated_risk =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sapply</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(c) {</span>
<span id="cb5-15">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mean</span>(severe[onset_day <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> c <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> severe <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;=</span> cutoff])</span>
<span id="cb5-16">  }), <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>),</span>
<span id="cb5-17">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">true_risk =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mean</span>(severe), <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)</span>
<span id="cb5-18">)</span>
<span id="cb5-19"></span>
<span id="cb5-20">epb_df</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>  shift_days estimated_risk true_risk
1          0          0.183     0.149
2          1          0.170     0.149
3          2          0.160     0.149
4          3          0.152     0.149</code></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb7" data-lst-cap="Sensitivity analysis for epidemic phase bias in R." style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb7-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(epb_df, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> shift_days, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> estimated_risk)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb7-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_line</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">colour =</span> blog_cols[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"red"</span>]], <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">linewidth =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.1</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb7-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_point</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">colour =</span> blog_cols[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"red"</span>]], <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">size =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb7-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_hline</span>(</span>
<span id="cb7-5">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">yintercept =</span> epb_df<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>true_risk[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>],</span>
<span id="cb7-6">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">linetype =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"dashed"</span>,</span>
<span id="cb7-7">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">colour =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gray40"</span></span>
<span id="cb7-8">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb7-9">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">annotate</span>(</span>
<span id="cb7-10">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"text"</span>,</span>
<span id="cb7-11">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> epb_df<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>true_risk[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>],</span>
<span id="cb7-12">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">label =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"True risk"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">vjust =</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">hjust =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">size =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.5</span></span>
<span id="cb7-13">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb7-14">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_x_continuous</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">name =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Shift (days)"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">breaks =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb7-15">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_y_continuous</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">name =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Estimated severe risk"</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.pkirwan.com/blog/study-designs/index_files/figure-html/lst-epidemic-phase-bias-1.png" class="img-fluid figure-img" alt="Line plot of estimated risk of severe outcome against the shift in days, falling from about 0.18 with no shift to about 0.15 with a shift of 3 days, approaching a dashed horizontal line at the true risk of about 0.15." width="672"></p>
</figure>
</div>
</div>
</div>
<p>When no shift is applied, the estimated risk of severe outcomes is biased upwards, because the faster symptom onset among severe cases means they are more likely to have an onset date within the observation window than mild cases. As the shift increases, the estimated risk approaches the true risk, which is recovered when the shift equals the true difference in time to symptom onset (3 days).</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
<span class="screen-reader-only">Note</span>Key takeaways
</div>
</div>
<div class="callout-body-container callout-body">
<ul>
<li>Different observational study designs (cross-sectional, case-control, cohort) are suited to different research questions and data collection scenarios.</li>
<li>Cross-sectional studies provide snapshots of prevalence at a single time point, while cohort studies follow exposure groups over time.</li>
<li>Case-control studies compare past exposures between those with and without outcomes, using odds ratios to measure associations.</li>
<li>Three main types of bias affect observational studies: information bias (measurement errors), collider bias (selection effects), and confounding (unmeasured common causes).</li>
<li>Epidemic phase bias is specific to infectious disease studies with time-varying incidence and rapid symptom onset.</li>
</ul>
</div>
</div>
</section>
</section>
<section id="references" class="level2">
<h2 class="anchored" data-anchor-id="references">References</h2>
<ul>
<li>Baker C. <a href="https://doi.org/10.21061/epidemiology">Epidemiology: Study Designs</a>. <em>Blacksburg</em>; 2023.</li>
<li>Bodicoat D. <a href="https://www.theanalysisfactor.com/study-designs-health-research-evidence-hierarchy/">Types of Study Designs in Health Research: The Evidence Hierarchy</a>.</li>
<li>Griffith GJ, Morris TT, Tudball MJ, <em>et al.</em> <a href="https://doi.org/10.1038/s41467-020-19478-2">Collider bias undermines our understanding of COVID-19 disease risk and severity</a>. <em>Nature Communications</em>. 11(1),5749.</li>
<li>Hernán MA, Robins JM. <a href="https://miguelhernan.org/whatifbook">Causal Inference: What If</a>. <em>CRC Press</em>; 2023, 312 pp.</li>
<li>Seaman SR, Nyberg T, Overton C, Pascall DJ, <em>et al.</em> <a href="https://doi.org/10.1177/09622802221107105">Adjusting for time of infection or positive test when estimating the risk of a post-infection outcome in an epidemic</a>. <em>Statistical Methods in Medical Research</em>. 2022;31(10):1942-58.</li>
<li>Wenzl T. <a href="https://doi.org/10.2760/564217">Smoking and COVID-19 - A review of studies suggesting a protective effect of smoking against COVID-19</a>. <em>Publications Office</em>. 2020.</li>
<li>Woodward M. <a href="https://doi.org/10.1201/b16343">Epidemiology: Study Design and Data Analysis</a>. <em>Chapman &amp; Hall/CRC Texts in Statistical Science</em>; 2013.</li>
</ul>
<div class="post-navigation">
<p><a href="../../blog/causal-inference/index.html">← Previous post</a></p>
<p><a href="../../index.html#blog">Back to all posts</a></p>
</div>


</section>

<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-reuse"><h2 class="anchored quarto-appendix-heading">Reuse</h2><div class="quarto-appendix-contents"><div><a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a></div></div></section><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre class="sourceCode code-with-copy quarto-appendix-bibtex"><code class="sourceCode bibtex">@online{kirwan2025,
  author = {Kirwan, Peter},
  title = {Part {VIII:} {Study} Designs and Biases},
  date = {2025-12-23},
  url = {https://www.pkirwan.com/blog/study-designs/},
  langid = {en}
}
</code></pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-kirwan2025" class="csl-entry quarto-appendix-citeas">
Kirwan, Peter. 2025. <span>“Part VIII: Study Designs and Biases.”</span>
December 23. <a href="https://www.pkirwan.com/blog/study-designs/">https://www.pkirwan.com/blog/study-designs/</a>.
</div></div></section></div> ]]></description>
  <category>Bias</category>
  <category>Confounding</category>
  <guid>https://www.pkirwan.com/blog/study-designs/</guid>
  <pubDate>Tue, 23 Dec 2025 00:00:00 GMT</pubDate>
  <media:content url="https://www.pkirwan.com/blog/study-designs/study-designs-banner.png" medium="image" type="image/png" height="52" width="144"/>
</item>
<item>
  <title>Part VII: Key concepts in causal inference</title>
  <dc:creator>Peter Kirwan</dc:creator>
  <link>https://www.pkirwan.com/blog/causal-inference/</link>
  <description><![CDATA[ 






<p>This is part seven of a series on statistical methods for infectious disease epidemiology, with a focus on time-to-event, or “survival”, data.</p>
<p>In this post I’ll introduce the concept of causal inference from observational data and provide an outline of three common methods to compute the average causal effect. For simplicity, the examples use a binary outcome rather than a time-to-event outcome, but the same ideas extend to survival data.</p>
<section id="assessing-causal-effects" class="level2">
<h2 class="anchored" data-anchor-id="assessing-causal-effects">Assessing causal effects</h2>
<p>In trial settings, well-designed randomised experiments, where the treated and untreated are theoretically exchangeable (or <em>exogenous</em>), provide a rigorous way to assess causal effects within a specific population. Under these ideal conditions, any observed association between the treatment and the outcome can be more confidently interpreted as causation, due to the minimisation of confounding and selection bias. However, even randomised trials have limitations, with potential issues including external validity or the <em>Hawthorne effect</em> - where participants modify their behaviour in response to being observed.</p>
<p>In contrast, observational data typically present more challenges in establishing causality due to the potential for unmeasured confounding and selection bias. If an explicit causal question is defined (e.g.&nbsp;the effect of a well-specified hypothetical intervention), and certain stringent conditions are fulfilled (such as no unmeasured confounding, positivity, and consistency) it becomes possible to make causal inferences from observational data. This approach, referred to as the <em>potential outcome framework</em>, requires careful consideration of the study design, choice of appropriate statistical methods, and transparent reporting of assumptions, with any causal claims depending on the plausibility of these assumptions.</p>
</section>
<section id="causal-diagrams" class="level2">
<h2 class="anchored" data-anchor-id="causal-diagrams">Causal diagrams and local independence</h2>
<p>Causal diagrams are a graphical tool used to visualise causal relationships. One class of causal diagrams is causal directed acyclic graphs (causal DAGs). In these graphs, nodes represent measurements or interventions at discrete times, and edges between nodes indicate causal effects, an example is shown in Figure&nbsp;1. The lack of an edge between nodes can be interpreted as the absence of a direct effect.</p>
<div id="fig-causal-dag" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-causal-dag-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell">
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.pkirwan.com/blog/causal-inference/index_files/figure-html/unnamed-chunk-2-1.png" class="img-fluid figure-img" alt="Causal diagram with three nodes. C has arrows to A and to Y, and A has an arrow to Y." width="384"></p>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-causal-dag-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;1: Example of a causal DAG representing discrete measurements for treatment, <img src="https://latex.codecogs.com/png.latex?A">, causes of treatment, <img src="https://latex.codecogs.com/png.latex?C">, and outcome, <img src="https://latex.codecogs.com/png.latex?Y">.
</figcaption>
</figure>
</div>
<p>Whilst causal DAGs are useful to describe relationships between discrete-time processes, they are poorly suited to describing causality in continuous-time, as changes in quantities or the occurrence of events are not represented. Instead, for continuous-time processes, the concept of <em>local independence</em> may be applied to consider how well a future value of an intensity process (such as a transition intensity in a multi-state model) is predicted by the past. Local independence can be viewed as <em>immediate causation</em>, and can be represented in a type of causal diagram known as a local independence graph. In these graphs, nodes represent stochastic processes and edges between nodes represent immediate causal influence, example shown in Figure&nbsp;2.</p>
<div id="fig-li-graph" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-li-graph-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell">
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.pkirwan.com/blog/causal-inference/index_files/figure-html/unnamed-chunk-3-1.png" class="img-fluid figure-img" alt="Local independence graph with three nodes. C has an arrow to A, and A has an arrow to Y. There is no arrow from C to Y." width="384"></p>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-li-graph-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;2: Example of a local independence graph representing continuous processes for treatment, <img src="https://latex.codecogs.com/png.latex?A">, causes of treatment, <img src="https://latex.codecogs.com/png.latex?C">, and outcome, <img src="https://latex.codecogs.com/png.latex?Y">. In local independence graphs only immediate causal influences are shown.
</figcaption>
</figure>
</div>
</section>
<section id="causal-inference" class="level2">
<h2 class="anchored" data-anchor-id="causal-inference">Causal inference from observational data</h2>
<p>To make causal inference from observational data we rely on being able to analyse the data as if treatment had been randomly assigned, conditional on a set of measured covariates <img src="https://latex.codecogs.com/png.latex?Z">. This is termed a <em>conditionally randomised</em> experiment.</p>
<p>Let <img src="https://latex.codecogs.com/png.latex?Y%20=%20(0:"> doesn’t experience outcome, <img src="https://latex.codecogs.com/png.latex?1:"> experiences outcome<img src="https://latex.codecogs.com/png.latex?)"> be a random variable for an observed outcome, and <img src="https://latex.codecogs.com/png.latex?A%20=%20(0:"> untreated, <img src="https://latex.codecogs.com/png.latex?1:"> treated<img src="https://latex.codecogs.com/png.latex?)"> be a random variable for an observed treatment, then:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5CPr(Y%20=%201%20%5Cmid%20A%20=%201)%0A"></p>
<p>is the probability of experiencing the outcome given treatment. Define the potential outcome under treatment <img src="https://latex.codecogs.com/png.latex?a"> as <img src="https://latex.codecogs.com/png.latex?Y%5Ea">, then the potential outcome under the observed treatment is: <img src="https://latex.codecogs.com/png.latex?Y%5EA%20=%20Y">.</p>
<section id="identifiability-conditions" class="level3">
<h3 class="anchored" data-anchor-id="identifiability-conditions">Identifiability conditions</h3>
<p>Three <em>identifiability conditions</em> are required for an observational study to be treated as a conditionally randomised experiment:</p>
<ol type="1">
<li><p><strong>Consistency</strong>: the values of treatment under comparison correspond to well-defined interventions that, in turn, correspond to the versions of treatment in the data, i.e.&nbsp;<img src="https://latex.codecogs.com/png.latex?Y%5Ea%20=%20Y"> for individuals with <img src="https://latex.codecogs.com/png.latex?A%20=%20a">.</p></li>
<li><p><strong>Exchangeability</strong>: the conditional probability of receiving every value of treatment depends only on measured covariates <img src="https://latex.codecogs.com/png.latex?Z">. This is alternatively phrased as: conditional on a set of measured covariates <img src="https://latex.codecogs.com/png.latex?Z">, the untreated group, had they been treated, would experience the same average outcome as the treated group, i.e.</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5CPr(Y%5Ea%20=%201%20%5Cmid%20A%20=%201,%20Z%20=%20z)%20=%20%5CPr(Y%5Ea%20=%201%20%5Cmid%20A%20=%200,%20Z%20=%20z)%0A"></p>
<p>or equivalently, <img src="https://latex.codecogs.com/png.latex?Y%5Ea%20%5Cmathrel%7B%5Cperp%5C!%5C!%5C!%5C!%5Cperp%7D%20A%20%5Cmid%20Z%20=%20z">, the counterfactual outcome and the observed treatment are independent within the covariate levels <img src="https://latex.codecogs.com/png.latex?Z%20=%20z">. Here, <img src="https://latex.codecogs.com/png.latex?%5Cmathrel%7B%5Cperp%5C!%5C!%5C!%5C!%5Cperp%7D"> is the notation for independence.</p></li>
<li><p><strong>Positivity</strong>: the probability of receiving every value of treatment <img src="https://latex.codecogs.com/png.latex?a"> conditional on <img src="https://latex.codecogs.com/png.latex?Z%20=%20z"> is positive, i.e.</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5CPr(A%20=%20a%20%5Cmid%20Z%20=%20z)%20%3E%200%20%5Cquad%5Ctext%7Bfor%20all%20%7D%20z%20%5Ctext%7B%20where%20%7D%20%5CPr(Z%20=%20z)%20%5Cneq%200%0A"></p></li>
</ol>
<p>Among these conditions, positivity can be checked empirically in observational studies (for example by looking for covariate levels where nobody is treated), whereas consistency relies on treatment being well-defined, and exchangeability relies on the assumption that all predictors of an outcome have been measured. It is usually impossible to guarantee exchangeability, but understanding the potential for biases such as confounding and collider bias (defined in the next post) can inform which covariates to include such that the assumption will be approximately true.</p>
<p>If the three identifiability conditions are fulfilled, a (hypothetical) randomised experiment, known as a <em>target trial</em>, may be emulated using causal inference from observational data, with the average causal effect quantified as <img src="https://latex.codecogs.com/png.latex?E(Y%5E%7Ba%20=%201%7D)%20-%20E(Y%5E%7Ba%20=%200%7D)">.</p>
</section>
<section id="r-example-confounding" class="level3">
<h3 class="anchored" data-anchor-id="r-example-confounding">R example</h3>
<p>The simulated example below creates a simple confounded observational dataset where a baseline covariate, <img src="https://latex.codecogs.com/png.latex?Z">, affects both treatment assignment and outcome risk. The crude treated-vs-untreated comparison can then be contrasted with the true average causal effect built into the simulation.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" data-lst-cap="Simulating confounding in an observational study in R." style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb1-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">set.seed</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2026</span>)</span>
<span id="cb1-2"></span>
<span id="cb1-3">n <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2000</span></span>
<span id="cb1-4">causal_data <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">data.frame</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">z =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rbinom</span>(n, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.45</span>))</span>
<span id="cb1-5"></span>
<span id="cb1-6">causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>y0 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rbinom</span>(n, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">plogis</span>(<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.2</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.2</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>z))</span>
<span id="cb1-7">causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>y1 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rbinom</span>(n, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">plogis</span>(<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.8</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.2</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>z))</span>
<span id="cb1-8">causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>a <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rbinom</span>(n, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">plogis</span>(<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.1</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.4</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>z))</span>
<span id="cb1-9">causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>y <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ifelse</span>(causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>a <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>y1, causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>y0)</span>
<span id="cb1-10"></span>
<span id="cb1-11">crude_rd <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mean</span>(causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>y[causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>a <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span></span>
<span id="cb1-12">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mean</span>(causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>y[causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>a <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>])</span>
<span id="cb1-13">true_ace  <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mean</span>(causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>y1 <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>y0)</span>
<span id="cb1-14"></span>
<span id="cb1-15"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(</span>
<span id="cb1-16">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">crude_risk_difference      =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(crude_rd, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>),</span>
<span id="cb1-17">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">true_average_causal_effect =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(true_ace, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)</span>
<span id="cb1-18">)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>     crude_risk_difference true_average_causal_effect 
                    -0.022                     -0.061 </code></pre>
</div>
</div>
<p>In this setup the crude comparison is biased because treated individuals are more likely to come from the higher-risk covariate stratum. The crude risk difference (-0.022) understates the protective effect of treatment compared with the true average causal effect (-0.061).</p>
</section>
</section>
<section id="causal-methods" class="level2">
<h2 class="anchored" data-anchor-id="causal-methods">Methods to compute the average causal effect</h2>
<p>Three commonly-used methods to compute the average causal effect are inverse probability weighting, matching, and standardisation.</p>
<section id="inverse-probability-weighting" class="level3">
<h3 class="anchored" data-anchor-id="inverse-probability-weighting">Inverse probability weighting</h3>
<p>The concept of inverse probability weighting is to assign weights to each individual in the cohort based on the inverse of the probability of receiving the observed treatment level, conditional on their covariates, <img src="https://latex.codecogs.com/png.latex?Z">. For example, a treated individual, <img src="https://latex.codecogs.com/png.latex?A%20=%201">, with a set of covariates <img src="https://latex.codecogs.com/png.latex?Z%20=%20z"> would be assigned a weight of <img src="https://latex.codecogs.com/png.latex?1/%5CPr(A%20=%201%20%5Cmid%20Z%20=%20z)">.</p>
<p>Conversely, an untreated individual, <img src="https://latex.codecogs.com/png.latex?A%20=%200">, with covariates <img src="https://latex.codecogs.com/png.latex?Z%20=%20z'"> would be assigned a weight of <img src="https://latex.codecogs.com/png.latex?1/%5CPr(A%20=%200%20%5Cmid%20Z%20=%20z')">. These weights are used to adjust for potential baseline confounders when estimating the causal effect of treatment, allowing the creation of a <em>pseudo-population</em> where treatment assignment is independent of the observed covariates.</p>
</section>
<section id="r-example-ipw" class="level3">
<h3 class="anchored" data-anchor-id="r-example-ipw">R example</h3>
<p>In R, this usually starts by fitting a propensity score model and then constructing the inverse-probability weights directly from the fitted probabilities.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" data-lst-cap="Estimating an inverse-probability weighted risk difference in R." style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb3-1">propensity_model <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">glm</span>(a <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> z, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">family =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">binomial</span>(), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> causal_data)</span>
<span id="cb3-2"></span>
<span id="cb3-3">causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>ps <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">predict</span>(propensity_model, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">type =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"response"</span>)</span>
<span id="cb3-4">causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>ipw <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ifelse</span>(</span>
<span id="cb3-5">  causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>a <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,</span>
<span id="cb3-6">  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>ps,</span>
<span id="cb3-7">  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> (<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>ps)</span>
<span id="cb3-8">)</span>
<span id="cb3-9"></span>
<span id="cb3-10">weighted_risk_treated <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">weighted.mean</span>(</span>
<span id="cb3-11">  causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>y[causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>a <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>],</span>
<span id="cb3-12">  causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>ipw[causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>a <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]</span>
<span id="cb3-13">)</span>
<span id="cb3-14">weighted_risk_untreated <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">weighted.mean</span>(</span>
<span id="cb3-15">  causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>y[causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>a <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>],</span>
<span id="cb3-16">  causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>ipw[causal_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>a <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]</span>
<span id="cb3-17">)</span>
<span id="cb3-18"></span>
<span id="cb3-19"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(</span>
<span id="cb3-20">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">ipw_risk_treated =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(weighted_risk_treated, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>),</span>
<span id="cb3-21">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">ipw_risk_untreated =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(weighted_risk_untreated, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>),</span>
<span id="cb3-22">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">ipw_risk_difference =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(</span>
<span id="cb3-23">    weighted_risk_treated <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> weighted_risk_untreated,</span>
<span id="cb3-24">    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span></span>
<span id="cb3-25">  )</span>
<span id="cb3-26">)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>   ipw_risk_treated  ipw_risk_untreated ipw_risk_difference 
              0.094               0.158              -0.064 </code></pre>
</div>
</div>
<p>The weighted risk difference should move back towards the target-trial estimand by rebalancing the covariate distribution between treatment groups.</p>
</section>
<section id="matching" class="level3">
<h3 class="anchored" data-anchor-id="matching">Matching</h3>
<p>Matching involves constructing a subset of the population in which the distribution of covariates, <img src="https://latex.codecogs.com/png.latex?Z">, is the same for the treated and untreated groups. This is typically achieved by pairing each individual with an individual in the other treatment group who has the same or similar covariate values. The causal effect can be estimated as the average difference in outcomes among the matched pairs. Note that matching only treated individuals to controls estimates the average effect in the treated, whereas matching individuals in both groups estimates the average effect in the whole population.</p>
</section>
<section id="r-example-matching" class="level3">
<h3 class="anchored" data-anchor-id="r-example-matching">R example</h3>
<p>Since <img src="https://latex.codecogs.com/png.latex?Z"> is binary, we can match exactly on <img src="https://latex.codecogs.com/png.latex?Z">. In the example below, each individual is matched at random (with replacement) to an individual in the opposite treatment group with the same value of <img src="https://latex.codecogs.com/png.latex?Z">, so that the matched outcome stands in for the unobserved potential outcome:</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb5" data-lst-cap="Exact matching on Z in R." style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb5-1">match_rd <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(d) {</span>
<span id="cb5-2">  d<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>y_match <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">NA_real_</span></span>
<span id="cb5-3">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> (z_val <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> (a_val <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) {</span>
<span id="cb5-4">    idx  <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">which</span>(d<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>z <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> z_val <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> d<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>a <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> a_val)</span>
<span id="cb5-5">    pool <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> d<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>y[d<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>z <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> z_val <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> d<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>a <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> a_val]</span>
<span id="cb5-6">    d<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>y_match[idx] <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> pool[<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sample.int</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">length</span>(pool), <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">length</span>(idx), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">replace =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>)]</span>
<span id="cb5-7">  }</span>
<span id="cb5-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mean</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ifelse</span>(d<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>a <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, d<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>y <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> d<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>y_match, d<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>y_match <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> d<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>y))</span>
<span id="cb5-9">}</span>
<span id="cb5-10"></span>
<span id="cb5-11"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">set.seed</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2026</span>)</span>
<span id="cb5-12"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">match_rd</span>(causal_data), <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>[1] -0.068</code></pre>
</div>
</div>
<p>Matching on <img src="https://latex.codecogs.com/png.latex?Z"> ensures the comparison group has the same covariate distribution as the treated group, removing the confounding contribution of <img src="https://latex.codecogs.com/png.latex?Z">.</p>
</section>
<section id="standardisation" class="level3">
<h3 class="anchored" data-anchor-id="standardisation">Standardisation</h3>
<p>Standardisation involves estimating the counterfactual risk using a weighted average of the risks (or standardisation of the risks) in each covariate level. For example, for a covariate <img src="https://latex.codecogs.com/png.latex?Z"> with two levels <img src="https://latex.codecogs.com/png.latex?(0,1)">:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5CPr(Y%5Ea%20=%201)%20=%20%5CPr(Y%20=%201%20%5Cmid%20Z%20=%201,%20A%20=%20a)%5CPr(Z%20=%201)%20+%20%5CPr(Y%20=%201%20%5Cmid%20Z%20=%200,%20A%20=%20a)%5CPr(Z%20=%200)%0A"></p>
<p>which generalises to: <img src="https://latex.codecogs.com/png.latex?%0A%5CPr(Y%5Ea%20=%201)%20=%20%5Csum_z%7B%5CPr(Y%20=%201%20%5Cmid%20Z%20=%20z,%20A%20=%20a)%5CPr(Z%20=%20z)%7D%0A"></p>
<p>The standardised mean <img src="https://latex.codecogs.com/png.latex?E(Y%5Ea)%20=%20%5Csum_z%7BE(Y%20%5Cmid%20Z%20=%20z,%20A%20=%20a)%5CPr(Z%20=%20z)%7D"> is known as the <em>g-formula</em>.</p>
</section>
<section id="r-example-standardisation" class="level3">
<h3 class="anchored" data-anchor-id="r-example-standardisation">R example</h3>
<p>In practice, standardisation means fitting an outcome model, predicting every individual’s outcome under both treatment levels, and then averaging those counterfactual predictions across the observed covariate distribution.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb7" data-lst-cap="Estimating a standardised risk difference with the g-formula in R." style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb7-1">outcome_model <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">glm</span>(y <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> a <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> z, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">family =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">binomial</span>(), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> causal_data)</span>
<span id="cb7-2"></span>
<span id="cb7-3">risk_if_treated <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">predict</span>(</span>
<span id="cb7-4">  outcome_model,</span>
<span id="cb7-5">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">newdata =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">transform</span>(causal_data, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">a =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>),</span>
<span id="cb7-6">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">type =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"response"</span></span>
<span id="cb7-7">)</span>
<span id="cb7-8">risk_if_untreated <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">predict</span>(</span>
<span id="cb7-9">  outcome_model,</span>
<span id="cb7-10">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">newdata =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">transform</span>(causal_data, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">a =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>),</span>
<span id="cb7-11">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">type =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"response"</span></span>
<span id="cb7-12">)</span>
<span id="cb7-13"></span>
<span id="cb7-14"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(</span>
<span id="cb7-15">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">standardised_risk_treated =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mean</span>(risk_if_treated), <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>),</span>
<span id="cb7-16">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">standardised_risk_untreated =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mean</span>(risk_if_untreated), <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>),</span>
<span id="cb7-17">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">standardised_risk_difference =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(</span>
<span id="cb7-18">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mean</span>(risk_if_treated <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> risk_if_untreated),</span>
<span id="cb7-19">    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span></span>
<span id="cb7-20">  )</span>
<span id="cb7-21">)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>   standardised_risk_treated  standardised_risk_untreated 
                       0.096                        0.159 
standardised_risk_difference 
                      -0.063 </code></pre>
</div>
</div>
</section>
</section>
<section id="comparing-methods" class="level2">
<h2 class="anchored" data-anchor-id="comparing-methods">Comparing methods</h2>
<p>Finally, the results from the three methods can be compared to each other and to the true average causal effect built into the simulation. Uncertainty is quantified using a non-parametric bootstrap, repeating each analysis in 500 resamples of the data.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb9" data-lst-cap="Comparing causal inference methods in R, with bootstrap 95% confidence intervals." style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb9-1">estimate_rd <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(d) {</span>
<span id="cb9-2">  ps  <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">predict</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">glm</span>(a <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> z, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">family =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">binomial</span>(), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> d), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">type =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"response"</span>)</span>
<span id="cb9-3">  w   <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ifelse</span>(d<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>a <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> ps, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> (<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> ps))</span>
<span id="cb9-4">  fit <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">glm</span>(y <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> a <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> z, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">family =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">binomial</span>(), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> d)</span>
<span id="cb9-5"></span>
<span id="cb9-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(</span>
<span id="cb9-7">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Crude =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mean</span>(d<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>y[d<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>a <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mean</span>(d<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>y[d<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>a <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]),</span>
<span id="cb9-8">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">IPW =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">weighted.mean</span>(d<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>y[d<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>a <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], w[d<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>a <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span></span>
<span id="cb9-9">      <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">weighted.mean</span>(d<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>y[d<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>a <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>], w[d<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>a <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]),</span>
<span id="cb9-10">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Matching =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">match_rd</span>(d),</span>
<span id="cb9-11">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Standardisation (g-formula)</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mean</span>(</span>
<span id="cb9-12">      <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">predict</span>(fit, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">transform</span>(d, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">a =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">type =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"response"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span></span>
<span id="cb9-13">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">predict</span>(fit, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">transform</span>(d, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">a =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">type =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"response"</span>)</span>
<span id="cb9-14">    )</span>
<span id="cb9-15">  )</span>
<span id="cb9-16">}</span>
<span id="cb9-17"></span>
<span id="cb9-18"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">set.seed</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2026</span>)</span>
<span id="cb9-19">estimates <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">estimate_rd</span>(causal_data)</span>
<span id="cb9-20">boot <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">t</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">replicate</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">500</span>, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">estimate_rd</span>(causal_data[<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sample</span>(n, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">replace =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>), ])))</span>
<span id="cb9-21"></span>
<span id="cb9-22">compare_df <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">data.frame</span>(</span>
<span id="cb9-23">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">method =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">factor</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">names</span>(estimates), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">levels =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rev</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">names</span>(estimates))),</span>
<span id="cb9-24">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">rd     =</span> estimates,</span>
<span id="cb9-25">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">lo     =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">apply</span>(boot, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, quantile, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.025</span>),</span>
<span id="cb9-26">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">hi     =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">apply</span>(boot, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, quantile, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.975</span>)</span>
<span id="cb9-27">)</span>
<span id="cb9-28"></span>
<span id="cb9-29"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(compare_df, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> rd, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> method)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb9-30">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_vline</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">xintercept =</span> true_ace, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">linetype =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"dashed"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">colour =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gray40"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb9-31">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">annotate</span>(</span>
<span id="cb9-32">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"text"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> true_ace, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.5</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">label =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"True ACE"</span>,</span>
<span id="cb9-33">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">hjust =</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">size =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.5</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">colour =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gray40"</span></span>
<span id="cb9-34">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb9-35">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_errorbar</span>(</span>
<span id="cb9-36">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">xmin =</span> lo, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">xmax =</span> hi, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">colour =</span> method <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Crude"</span>),</span>
<span id="cb9-37">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">orientation =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"y"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">width =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.15</span></span>
<span id="cb9-38">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb9-39">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_point</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">colour =</span> method <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Crude"</span>), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">size =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb9-40">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_colour_manual</span>(</span>
<span id="cb9-41">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"TRUE"</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> blog_cols[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"dark"</span>]], <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"FALSE"</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> blog_cols[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"red"</span>]]),</span>
<span id="cb9-42">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">guide =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"none"</span></span>
<span id="cb9-43">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb9-44">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_x_continuous</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">name =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Risk difference"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb9-45">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_y_discrete</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">name =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">NULL</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.pkirwan.com/blog/causal-inference/index_files/figure-html/lst-compare-methods-1.png" class="img-fluid figure-img" alt="Dot plot of risk differences with 95% confidence intervals for the crude, IPW, matching and standardisation estimates, and a dashed vertical line at the true average causal effect. The crude estimate is close to zero, while the three adjusted estimates are close to the true value of about minus 0.06." width="672"></p>
</figure>
</div>
</div>
</div>
<p>We can see that the crude risk difference is biased towards zero (the protective effect of treatment is understated) due to confounding, while the three methods to adjust for confounding (IPW, matching, and standardisation via the g-formula) all give estimates close to the true average causal effect, with confidence intervals that include it. The confidence intervals reflect sampling variability only, and cannot account for unmeasured confounding.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
<span class="screen-reader-only">Note</span>Key takeaways
</div>
</div>
<div class="callout-body-container callout-body">
<ul>
<li>Randomised trials provide strong evidence for causation, but observational data can also support causal inference under strict conditions.</li>
<li>Causal diagrams (DAGs) help visualise relationships between variables, while local independence graphs represent continuous-time causal processes.</li>
<li>Three key conditions enable causal inference from observational data: consistency, exchangeability, and positivity.</li>
<li>Exchangeability (no unmeasured confounding) is usually the most challenging assumption to verify in practice.</li>
<li>Three main methods estimate causal effects: inverse probability weighting, matching, and standardisation (g-formula).</li>
<li>Each method adjusts for measured confounding in different ways: inverse probability weighting creates a pseudo-population, matching creates a balanced matched sample, and standardisation averages over a target covariate distribution.</li>
</ul>
</div>
</div>
</section>
<section id="coming-next" class="level2">
<h2 class="anchored" data-anchor-id="coming-next">Coming next</h2>
<p>In the final post of this series, I’ll explore different observational study designs and several of the biases that can affect inference in observational research: information bias, collider bias, confounding, and epidemic phase bias.</p>
</section>
<section id="references" class="level2">
<h2 class="anchored" data-anchor-id="references">References</h2>
<ul>
<li>Aalen OO, Røysland K, Gran JM, Kouyos R <em>et al.</em> <a href="https://doi.org/10.1177/0962280213520436">Can we believe the DAGs? A comment on the relationship between causal DAGs and mechanisms</a>. <em>Stat. Methods Med. Res.</em> 2016; 25(5), pp.&nbsp;2294-2314.</li>
<li>Didelez V. <a href="https://doi.org/10.1111/j.1467-9868.2007.00634.x">Graphical Models for Marked Point Processes Based on Local Independence</a>. <em>J. R. Stat. Soc. Series B Stat. Methodol</em>. 2008; 70(1), pp.245-264.</li>
<li>Griffith GJ, Morris TT, Tudball MJ, <em>et al.</em> <a href="https://doi.org/10.1038/s41467-020-19478-2">Collider bias undermines our understanding of COVID-19 disease risk and severity</a>. <em>Nature Communications</em>. 11(1),5749.</li>
<li>Hernán MA, Robins JM. <a href="https://doi.org/10.1136/jech.2004.029496">Estimating causal effects from epidemiological data</a>. <em>J. Epidemiol. Community Health</em>. 2006;60(7), pp.578-586.</li>
<li>Hernán MA, Robins JM. <a href="https://miguelhernan.org/whatifbook">Causal Inference: What If</a>. <em>CRC Press</em>; 2023, 312 pp.</li>
<li>McCambridge J, Witton J, Elbourne DR. <a href="https://doi.org/10.1016/j.jclinepi.2013.08.015">Systematic review of the Hawthorne effect: new concepts are needed to study research participation effects</a>. <em>J. Clin. Epidemiol.</em> 2014;67(3),pp.267-277.</li>
</ul>
<div class="post-navigation">
<p><a href="../../blog/statistical-inference-msms/index.html">← Previous post</a></p>
<p><a href="../../index.html#blog">Back to all posts</a></p>
<p><a href="../../blog/study-designs/index.html">Next post →</a></p>
</div>


</section>

<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-reuse"><h2 class="anchored quarto-appendix-heading">Reuse</h2><div class="quarto-appendix-contents"><div><a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a></div></div></section><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre class="sourceCode code-with-copy quarto-appendix-bibtex"><code class="sourceCode bibtex">@online{kirwan2025,
  author = {Kirwan, Peter},
  title = {Part {VII:} {Key} Concepts in Causal Inference},
  date = {2025-11-18},
  url = {https://www.pkirwan.com/blog/causal-inference/},
  langid = {en}
}
</code></pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-kirwan2025" class="csl-entry quarto-appendix-citeas">
Kirwan, Peter. 2025. <span>“Part VII: Key Concepts in Causal
Inference.”</span> November 18. <a href="https://www.pkirwan.com/blog/causal-inference/">https://www.pkirwan.com/blog/causal-inference/</a>.
</div></div></section></div> ]]></description>
  <category>Causal inference</category>
  <category>DAGs</category>
  <guid>https://www.pkirwan.com/blog/causal-inference/</guid>
  <pubDate>Tue, 18 Nov 2025 00:00:00 GMT</pubDate>
  <media:content url="https://www.pkirwan.com/blog/causal-inference/causal-inference-banner.png" medium="image" type="image/png" height="62" width="144"/>
</item>
<item>
  <title>Part VI: Statistical inference for multi-state models</title>
  <dc:creator>Peter Kirwan</dc:creator>
  <link>https://www.pkirwan.com/blog/statistical-inference-msms/</link>
  <description><![CDATA[ 






<p>This is part six of a series on statistical methods for infectious disease epidemiology, with a focus on time-to-event, or “survival”, data.</p>
<p>In this post I’ll describe two statistical inference methods (non-parametric and parametric multi-state survival models) and the conditions under which these multi-state methods can be used to investigate intermittently-observed data.</p>
<section id="aalen-johansen" class="level2">
<h2 class="anchored" data-anchor-id="aalen-johansen">Aalen-Johansen estimator</h2>
<p>The non-parametric Aalen-Johansen estimator can be used to estimate the transition probability matrix, <img src="https://latex.codecogs.com/png.latex?%5Cmathbf%7BP%7D(t)"> for a Markov process with a finite number of states. Firstly, let <img src="https://latex.codecogs.com/png.latex?%5Cmathbf%7BA%7D(t)"> be the matrix of cumulative transition intensities from state <img src="https://latex.codecogs.com/png.latex?r"> to state <img src="https://latex.codecogs.com/png.latex?s">:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Cmathbf%7BA%7D(t)%20=%20A_%7Br,s%7D(t)%20=%0A%5Cbegin%7Bcases%7D%0A%5Cint_%7B0%7D%5E%7Bt%7D%7Bq_%7Br,s%7D(u)%20du%7D%20&amp;%20%5Ctext%7Bif%20%7D%20r%5Cneq%20s%20%5C%5C%0A-%5Csum_%7Bs%20%5Cneq%20r%7D%7BA_%7Br,s%7D(t)%7D%20&amp;%20%5Ctext%7Bif%20%7D%20r%20=%20s%0A%5Cend%7Bcases%7D%0A"></p>
<p>The transition probability matrix for this process can be represented as the (time-ordered) matrix product:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Cmathbf%7BP%7D(t)%20=%20%5Cprod_%7Bk%20=%201%7D%5E%7BK%7D%7B%5Cleft(%5Cmathbb%7BI%7D+%5CDelta%5Cmathbf%7BA%7D(t_k)%5Cright)%7D%0A"></p>
<p>where <img src="https://latex.codecogs.com/png.latex?t_1%20%3C%20%5Cldots%20%3C%20t_K%20%5Cleq%20t"> are the times at which transitions take place, <img src="https://latex.codecogs.com/png.latex?%5Cmathbb%7BI%7D"> is the identity matrix, <img src="https://latex.codecogs.com/png.latex?%5CDelta%5Cmathbf%7BA%7D(t_k)%20=%20%5Cmathbf%7BA%7D(t_k)%20-%20%5Cmathbf%7BA%7D(t_k%20%5Cmbox%7B-%7D)">, and <img src="https://latex.codecogs.com/png.latex?t_k%20%5Cmbox%7B-%7D"> represents the instant before time <img src="https://latex.codecogs.com/png.latex?t_k">. Substituting the Nelson-Aalen estimator for <img src="https://latex.codecogs.com/png.latex?%5Cmathbf%7BA%7D(t)">, then the Aalen-Johansen estimate of the transition probability matrix is:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Cmathbf%7B%7B%5Chat%7BP%7D%7D%7D(t)%20=%20%5Chat%7BP%7D_%7Br,s%7D(t)%20=%20%5Cprod_%7Bk%20=%0A1%7D%5E%7BK%7D%7B%5Cleft(%5Cmathbb%7BI%7D_%7Br,s%7D+%5CDelta%5Chat%7BA%7D_%7Br,s%7D(t_k)%5Cright)%7D%0A"></p>
<p>with:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5CDelta%5Chat%7BA%7D_%7Br,s%7D(t_k)%20=%0A%5Cbegin%7Bcases%7D%0A%5Cfrac%7B%5CDelta%20N_%7Br,s%7D(t_k)%7D%7BY_%7Br%7D(t_k%20%5Cmbox%7B-%7D)%7D%20&amp;%20%5Ctext%7Bif%20%7D%20r%5Cneq%20s%20%5C%5C%0A%5Cfrac%7B-%5CDelta%20N_%7Bs%7D(t_k)%7D%7BY_%7Bs%7D(t_k%20%5Cmbox%7B-%7D)%7D%20&amp;%20%5Ctext%7Bif%20%7D%20r%20=%20s%0A%5Cend%7Bcases%7D%0A"></p>
<p>where <img src="https://latex.codecogs.com/png.latex?%5CDelta%20N_%7Br,s%7D(t_k)"> is the number of transitions from state <img src="https://latex.codecogs.com/png.latex?r"> to state <img src="https://latex.codecogs.com/png.latex?s"> at time <img src="https://latex.codecogs.com/png.latex?t_k">, <img src="https://latex.codecogs.com/png.latex?%5CDelta%20N_%7Bs%7D(t_k)"> is the number of transitions away from state <img src="https://latex.codecogs.com/png.latex?s"> at time <img src="https://latex.codecogs.com/png.latex?t_k">, and <img src="https://latex.codecogs.com/png.latex?Y_%7Br%7D(t_k%20%5Cmbox%7B-%7D)"> is the number of individuals in state <img src="https://latex.codecogs.com/png.latex?r"> just before time <img src="https://latex.codecogs.com/png.latex?t_k">.</p>
<p>The Aalen-Johansen estimator requires the times of transitions between states to be observed exactly (together with the state occupied by each individual at all times). It is therefore not directly applicable to intermittently-observed data, where the times of transitions are interval-censored; this is the main motivation for the likelihood-based approach described below.</p>
</section>
<section id="multi-state-mixture-models" class="level2">
<h2 class="anchored" data-anchor-id="multi-state-mixture-models">Multi-state mixture models</h2>
<p>For a general multi-state competing risks mixture model, assume that an individual <img src="https://latex.codecogs.com/png.latex?i"> who begins in state <img src="https://latex.codecogs.com/png.latex?r"> makes a transition to a (pre-assigned) destination state <img src="https://latex.codecogs.com/png.latex?s">. Let <img src="https://latex.codecogs.com/png.latex?I_%7Bi,r%7D"> be the indicator variable which determines which transition will occur, the transition intensity at time <img src="https://latex.codecogs.com/png.latex?t"> is:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0Aq_%7Bi,r,s%7D(t)%20=%0A%5Cbegin%7Bcases%7D%0Aq%5E%7B*%7D_%7Bi,r,s%7D(t)%20&amp;%20%5Ctext%7Bif%20%7D%20I_%7Bi,r%7D%20=%20s%20%5C%5C%0A0%20&amp;%20%5Ctext%7Botherwise%7D%0A%5Cend%7Bcases%7D%0A"></p>
<p>where <img src="https://latex.codecogs.com/png.latex?q%5E%7B*%7D_%7Bi,r,s%7D(t)"> is the transition intensity for the transition which occurs. The probability of transition to state <img src="https://latex.codecogs.com/png.latex?s"> is defined as:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Cbegin%7Balign*%7D%0A%5Cpi_%7Br,s%7D%20&amp;%20=%20%5CPr(I_%7Bi,r%7D%20=%20s)%0A%5Cend%7Balign*%7D%0A"></p>
<p>Let <img src="https://latex.codecogs.com/png.latex?T_%7Br,s%7D"> be the the time from entering state <img src="https://latex.codecogs.com/png.latex?r"> to moving to state <img src="https://latex.codecogs.com/png.latex?s">, given that this transition occurs (i.e.&nbsp;the conditional sojourn time). A parametric distribution with parameters <img src="https://latex.codecogs.com/png.latex?%5Ctheta_%7Br,s%7D"> and conditional density <img src="https://latex.codecogs.com/png.latex?f_%7Br,s%7D(.%20%5Cmid%20%5Ctheta_%7Br,s%7D)"> may be used to model <img src="https://latex.codecogs.com/png.latex?T_%7Br,s%7D">.</p>
<section id="transition-probabilities" class="level3">
<h3 class="anchored" data-anchor-id="transition-probabilities">Transition probabilities</h3>
<p>The probabilities of competing events <img src="https://latex.codecogs.com/png.latex?%5Cpi_%7Br,s%7D"> can be related to a set of <img src="https://latex.codecogs.com/png.latex?m"> covariates <img src="https://latex.codecogs.com/png.latex?%5Cboldsymbol%7Bz%7D%20=%20%5C%7Bz_1,%20%5Cldots,%20z_m%5C%7D"> via multinomial logistic regression. Define as <img src="https://latex.codecogs.com/png.latex?S_r"> the set of all competing states after <img src="https://latex.codecogs.com/png.latex?r">, then the logit of transition to a given state <img src="https://latex.codecogs.com/png.latex?j%20%5Cin%20S_r"> vs.&nbsp;transition to a baseline state <img src="https://latex.codecogs.com/png.latex?0%20%5Cin%20S_r"> is:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Cln%5Cleft(%5Cfrac%7B%5Cpi_%7Br,j%7D(%5Cboldsymbol%7Bz%7D)%7D%7B%5Cpi_%7Br,0%7D(%5Cboldsymbol%7Bz%7D)%7D%5Cright)%20=%20%5Calpha_%7Br,j%7D%20+%0A%5Cboldsymbol%7B%5Cbeta%7D_%7Br,j%7D%5E%5Cmathsf%7BT%7D%20%5Cboldsymbol%7Bz%7D%0A"></p>
<p>with <img src="https://latex.codecogs.com/png.latex?%5Calpha_%7Br,j%7D"> and <img src="https://latex.codecogs.com/png.latex?%5Cboldsymbol%7B%5Cbeta%7D_%7Br,j%7D%20=%20%5C%7B%5Cbeta_%7Br,j,k%7D;%5C;%20k%20=%201,%20%5Cldots%20m%5C%7D"> being regression coefficients for the probability of transition to state <img src="https://latex.codecogs.com/png.latex?j">.</p>
<p>Meanwhile, parameters <img src="https://latex.codecogs.com/png.latex?%5Ctheta_%7Br,s%7D"> of the time to transition distribution can be related to a different (or identical) set of <img src="https://latex.codecogs.com/png.latex?l"> covariates <img src="https://latex.codecogs.com/png.latex?%5Cboldsymbol%7Bx%7D%20=%20%5C%7Bx_1,%20%5Cldots,%20x_l%5C%7D"> via a log-linear model (for parameters which are constrained to be positive) with coefficients <img src="https://latex.codecogs.com/png.latex?%5Cgamma_%7Br,s%7D"> and <img src="https://latex.codecogs.com/png.latex?%5Cboldsymbol%7B%5Comega%7D_%7Br,s%7D%20=%20%5C%7B%5Comega_%7Br,s,k%7D;%5C;%20k%20=%201,%20%5Cldots,%20l%5C%7D">:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Clog(%5Ctheta_%7Br,s%7D(%5Cboldsymbol%7Bx%7D))=%5Cgamma_%7Br,s%7D%20+%20%5Cboldsymbol%7B%5Comega%7D_%7Br,s%7D%5E%5Cmathsf%7BT%7D%20%5Cboldsymbol%7Bx%7D%0A"></p>
<p>For most parametric time to transition distributions `accelerated failure time’ models are considered, where the covariates affect the rate of progression of time, i.e.&nbsp;the survival function <img src="https://latex.codecogs.com/png.latex?S(t%20%5Cmid%20%5Cboldsymbol%7Bx%7D)"> for an individual at time <img src="https://latex.codecogs.com/png.latex?t"> with covariates <img src="https://latex.codecogs.com/png.latex?%5Cboldsymbol%7Bx%7D"> is related to the baseline survival <img src="https://latex.codecogs.com/png.latex?S%5E%7B(0)%7D"> via:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0AS(t%5Cmid%20%5Cboldsymbol%7Bx%7D)%20=%20S%5E%7B(0)%7D%5Cleft(%5Cexp(%5Cboldsymbol%7B%5Ceta%7D%5E%5Cmathsf%7BT%7D%5Cboldsymbol%7Bx%7D)t%5Cright)%0A"></p>
<p>where <img src="https://latex.codecogs.com/png.latex?%5Cboldsymbol%7B%5Ceta%7D"> is a vector of regression coefficients.</p>
</section>
<section id="likelihood-contributions" class="level3">
<h3 class="anchored" data-anchor-id="likelihood-contributions">Likelihood contributions</h3>
<p>The likelihood contributions are as follows:</p>
<ul>
<li><p>For an individual who enters state <img src="https://latex.codecogs.com/png.latex?r"> and reaches state <img src="https://latex.codecogs.com/png.latex?s%20%5Cin%20S_r"> at time <img src="https://latex.codecogs.com/png.latex?t">: <img src="https://latex.codecogs.com/png.latex?%0Al%20=%20%5Cpi_%7Br,s%7D%20f_%7Br,s%7D(t)%0A"></p></li>
<li><p>For an individual who is censored in state <img src="https://latex.codecogs.com/png.latex?r"> at time <img src="https://latex.codecogs.com/png.latex?t">: <img src="https://latex.codecogs.com/png.latex?%0Al_c%20=%20%5Csum_%7Bs%20%5Cin%20S_r%7D%5Cpi_%7Br,s%7D(1-F_%7Br,s%7D(t))%0A"></p>
<p>where <img src="https://latex.codecogs.com/png.latex?F_%7Br,s%7D(t)%20=%20%5Cint_0%5Et%20f_%7Br,s%7D(x)dx"> is the conditional cumulative distribution of the time to transition from state <img src="https://latex.codecogs.com/png.latex?r"> to state <img src="https://latex.codecogs.com/png.latex?s">, given that this transition occurs.</p></li>
</ul>
</section>
</section>
<section id="accounting-for-censoring" class="level2">
<h2 class="anchored" data-anchor-id="accounting-for-censoring">Accounting for censoring</h2>
<p>As described in <a href="../../blog/classical-survival-methods/index.html#likelihood-estimation">part III of this series</a>, survival models may be specified to account for censoring and truncation in observed data by careful consideration and construction of the likelihood function. Multi-state survival models, in particular, are well-suited to investigating interval-censored, or <em>intermittently-observed</em> data.</p>
<p>In the interval censoring figure from <a href="../../blog/survival-analysis/index.html#interval-censoring">part II of this series</a>, changes in an underlying process were detected with an intermittent observation scheme. Depending on the nature of the underlying process, less frequent and/or irregular observation may result in transitions being undetected, as shown in Figure&nbsp;1 below. This could be an issue for survival models, particularly when there is a dependency between the observation times and the underlying process.</p>
<div id="fig-intermittent-observation" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-intermittent-observation-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell">
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.pkirwan.com/blog/statistical-inference-msms/index_files/figure-html/unnamed-chunk-2-1.png" class="img-fluid figure-img" alt="Step plot of an underlying process which moves from state 1 to state 2 at week 3 and back to state 1 at week 7. Observations at weeks 2, 8 and 12 (dashed lines) all find the process in state 1, so both transitions are missed. Planned observations at weeks 4, 6 and 10 (dotted lines) were missed." width="672"></p>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-intermittent-observation-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;1: Example of intermittently-observed data with missed observations for an underlying process.
</figcaption>
</figure>
</div>
<p>An observation scheme is said to be <em>non-informative</em> if the likelihood is proportional to a scenario where observation times were fixed in advance and chosen independently of the underlying process. For example, a study with clinic visits scheduled every four weeks regardless of symptoms is closer to non-informative than a study where extra visits are triggered by clinical deterioration. With a non-informative observation scheme then multi-state models can correctly account for intermittently-observed data.</p>
<p>For a Markov multi-state model, the likelihood for intermittently-observed data only requires the states occupied at the observation times. An individual <img src="https://latex.codecogs.com/png.latex?i"> observed in states <img src="https://latex.codecogs.com/png.latex?s_0,%20s_1,%20%5Cldots,%20s_J"> at times <img src="https://latex.codecogs.com/png.latex?t_0,%20t_1,%20%5Cldots,%20t_J"> contributes the product of the transition probabilities between successive observations, regardless of any unobserved transitions in between:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0Al_i%20=%20%5Cprod_%7Bj=1%7D%5E%7BJ%7D%20P_%7Bs_%7Bj-1%7D,%20s_j%7D(t_%7Bj-1%7D,%20t_j)%0A"></p>
<p>where, for a time-homogeneous model, <img src="https://latex.codecogs.com/png.latex?%5Cmathbf%7BP%7D(t_%7Bj-1%7D,%20t_j)%20=%20%5Cexp%5Cleft((t_j%20-%20t_%7Bj-1%7D)%5Cmathbf%7BQ%7D%5Cright)"> as described in <a href="../../blog/multi-state-models/index.html">part V of this series</a>.</p>
</section>
<section id="implementing-multi-state-models" class="level2">
<h2 class="anchored" data-anchor-id="implementing-multi-state-models">Implementing multi-state models</h2>
<p>A number of sophisticated statistical software packages exist to implement frequentist and Bayesian survival and multi-state models using the <code>R</code> programming language. Frequentist maximum likelihood estimation tends to be less computationally intensive than Bayesian inference, and the latter may require integrating over a vast number of parameters, which is usually impracticable for higher dimensions. Instead, algorithms which simulate from the posterior distribution are often used to evaluate features of these integrals. Markov Chain Monte Carlo (MCMC) algorithms have been widely used for this application.</p>
<p>There are several specialised modelling packages available to fit multi-state models, including: <a href="https://github.com/therneau/survival"><code>survival</code></a>, <a href="https://chjackson.github.io/msm/"><code>msm</code></a>, <a href="https://cran.r-project.org/package=mstate"><code>mstate</code></a>, <a href="https://cran.r-project.org/package=etm"><code>etm</code></a> and <a href="https://chjackson.github.io/flexsurv/index.html"><code>flexsurv</code></a> which fit models using maximum likelihood or non-parametric estimators, and <a href="https://mcmc-jags.sourceforge.io/"><code>JAGS</code></a> and <a href="https://mc-stan.org/"><code>Stan</code></a> which fit Bayesian models using MCMC.</p>
<p>For HIV back-calculation specifically, the <a href="https://pkirwan.github.io/cd4backcalc/"><code>cd4backcalc</code></a> package implements Bayesian, discrete-time, multi-state CD4-staged back-calculation models in Stan.</p>
<p>Two useful online tutorials for running statistical inference for survival and multi-state models are:</p>
<ul>
<li><p><a href="https://www.emilyzabor.com/survival-analysis-in-r.html">Survival analysis in R</a> by Emily C. Zabor</p></li>
<li><p><a href="https://chjackson.github.io/msm/msmcourse/">Multi-state modelling with msm: a practical course</a> by Christopher Jackson</p></li>
</ul>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
<span class="screen-reader-only">Note</span>Key takeaways
</div>
</div>
<div class="callout-body-container callout-body">
<ul>
<li>The Aalen-Johansen estimator extends the Kaplan-Meier approach to provide non-parametric estimates of transition probabilities in multi-state models, provided that transitions are observed exactly.</li>
<li>Multi-state mixture models allow for different transition types with their own probability distributions and covariate effects.</li>
<li>Intermittently-observed data with interval censoring can be properly handled by likelihood-based multi-state models when observation schemes are non-informative.</li>
<li>Covariates can influence both the probability of transitions between states and the timing of those transitions.</li>
<li>Both frequentist (maximum likelihood) and Bayesian (MCMC) approaches are available for fitting multi-state models, with several specialised <code>R</code> packages providing implementation.</li>
</ul>
</div>
</div>
</section>
<section id="coming-next" class="level2">
<h2 class="anchored" data-anchor-id="coming-next">Coming next</h2>
<p>In the next post I’ll introduce the concept of causal inference from observational data and provide an outline of three common methods to compute the average causal effect.</p>
</section>
<section id="references" class="level2">
<h2 class="anchored" data-anchor-id="references">References</h2>
<ul>
<li>Andersen PK, Borgan O, Gill RD, Keiding N. <a href="http://dx.doi.org/10.1007/978-1-4612-4348-9">Statistical models based on counting processes</a>. <em>Springer</em>; 1996. 784 p.</li>
<li>Fagerland MW, Hosmer DW, Bofin AM. <a href="http://dx.doi.org/10.1002/sim.3202">Multinomial goodness-of-fit tests for logistic regression models</a>. <em>Stat Med</em>. 2008 Sep 20 [cited 2024 Feb 17];27(21):4238-53.</li>
<li>Ghani AC, Donnelly CA, Cox DR, <em>et al</em>. <a href="http://dx.doi.org/10.1093/aje/kwi230">Methods for estimating the case fatality ratio for a novel, emerging infectious disease</a>. <em>Am J Epidemiol</em>. 2005 Sep 1;162(5):479-86.</li>
<li>Grüger J, Kay R, Schumacher M. <a href="https://www.ncbi.nlm.nih.gov/pubmed/1912263">The validity of inferences based on incomplete observations in disease state models</a>. <em>Biometrics</em>. 1991 Jun;47(2):595-605.</li>
<li>Klein JP, Moeschberger ML. <a href="https://play.google.com/store/books/details?id=KSq0e-6VFJ0C">Survival Analysis: Techniques for Censored and Truncated Data</a>. <em>Springer Science &amp; Business Media</em>; 2005. 538 p.</li>
<li>van den Hout A. <a href="https://doi.org/10.1201/9781315374321">Multi-State Survival Models for Interval-Censored Data</a>. <em>CRC Press</em>; 2016. 238 p.</li>
<li>Young GA, Smith RL. <a href="http://dx.doi.org/10.1017/cbo9780511755392">Essentials of Statistical Inference</a>. <em>Cambridge University Press</em>; 2005.</li>
<li>Zhao H, Li Y, Sun J. <a href="http://dx.doi.org/10.1002/cjs.11143">Analyzing panel count data with a dependent observation process and a terminal event</a>. <em>Can J Stat</em>. 2013 Mar;41(1):174-91.</li>
</ul>
<div class="post-navigation">
<p><a href="../../blog/multi-state-models/index.html">← Previous post</a></p>
<p><a href="../../index.html#blog">Back to all posts</a></p>
<p><a href="../../blog/causal-inference/index.html">Next post →</a></p>
</div>


</section>

<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-reuse"><h2 class="anchored quarto-appendix-heading">Reuse</h2><div class="quarto-appendix-contents"><div><a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a></div></div></section><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre class="sourceCode code-with-copy quarto-appendix-bibtex"><code class="sourceCode bibtex">@online{kirwan2025,
  author = {Kirwan, Peter},
  title = {Part {VI:} {Statistical} Inference for Multi-State Models},
  date = {2025-10-21},
  url = {https://www.pkirwan.com/blog/statistical-inference-msms/},
  langid = {en}
}
</code></pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-kirwan2025" class="csl-entry quarto-appendix-citeas">
Kirwan, Peter. 2025. <span>“Part VI: Statistical Inference for
Multi-State Models.”</span> October 21. <a href="https://www.pkirwan.com/blog/statistical-inference-msms/">https://www.pkirwan.com/blog/statistical-inference-msms/</a>.
</div></div></section></div> ]]></description>
  <category>Multi-state models</category>
  <category>Statistical inference</category>
  <guid>https://www.pkirwan.com/blog/statistical-inference-msms/</guid>
  <pubDate>Tue, 21 Oct 2025 00:00:00 GMT</pubDate>
  <media:content url="https://www.pkirwan.com/blog/statistical-inference-msms/statistical-inference-banner.png" medium="image" type="image/png" height="68" width="144"/>
</item>
<item>
  <title>Part V: Multi-state models</title>
  <dc:creator>Peter Kirwan</dc:creator>
  <link>https://www.pkirwan.com/blog/multi-state-models/</link>
  <description><![CDATA[ 






<p>This is part five of a series on statistical methods for infectious disease epidemiology, with a focus on time-to-event, or “survival”, data.</p>
<section id="multi-state-survival-models" class="level2">
<h2 class="anchored" data-anchor-id="multi-state-survival-models">Multi-state survival models</h2>
<p>When disease processes are more complex, or when intermediate events may influence the final outcome, the standard survival methods described so far (<a href="../../blog/classical-survival-methods/index.html">classical survival methods</a> and <a href="../../blog/competing-risks-methods/index.html">competing risks methods</a>) may be insufficient to explore the effects of treatment on these outcomes. In these cases, multi-state models, which are more flexible and hence better able to investigate the different pathways that patients may experience, can be applied. These models allow for joint estimation of features of the underlying process and the associated hazards of transition for a set of given covariates, and implicitly account for competing risks.</p>
<p>This post provides an introduction to the theory of multi-state processes and describes how these relate to continuous-time and discrete-time multi-state models.</p>
</section>
<section id="stochastic-processes" class="level2">
<h2 class="anchored" data-anchor-id="stochastic-processes">Stochastic processes underlying multi-state models</h2>
<p>Multi-state models combine statistical inference with the theory of stochastic processes.</p>
<section id="parameter-processes" class="level3">
<h3 class="anchored" data-anchor-id="parameter-processes">Discrete and continuous parameter processes</h3>
<p>A stochastic process is formally defined as a collection of random variables <img src="https://latex.codecogs.com/png.latex?%5C%7BX(t),%5C;%20t%20%5Cin%20T%5C%7D">, indexed by a parameter such as time, which varies in a mathematical index set <img src="https://latex.codecogs.com/png.latex?T">. The variable <img src="https://latex.codecogs.com/png.latex?X(t)"> is the state of the process at time <img src="https://latex.codecogs.com/png.latex?t">, and the set <img src="https://latex.codecogs.com/png.latex?%5Cmathcal%7BS%7D"> of all possible values of <img src="https://latex.codecogs.com/png.latex?X(t)"> is termed the <em>state space</em>.</p>
<p>Two important cases of stochastic processes are discrete parameter processes, when <img src="https://latex.codecogs.com/png.latex?T%20=%20%5C%7B%5Cpm1,%20%5Cpm2,%20%5Cpm3,%20%5Cdots%5C%7D">, and continuous parameter processes, when <img src="https://latex.codecogs.com/png.latex?T%20=%20%5C%7Bt:-%5Cinfty%20%3C%20t%20%3C%20%5Cinfty%5C%7D">. Both may be restricted to the positive domain, in which case the parameter <img src="https://latex.codecogs.com/png.latex?t"> may be used to represent time, and these processes are termed ‘discrete-time’ and ‘continuous-time’ processes.</p>
</section>
<section id="counting-processes" class="level3">
<h3 class="anchored" data-anchor-id="counting-processes">Counting processes</h3>
<p>In survival analyses, the focus is typically on observing events as they occur over time, forming a class of stochastic process known as a <em>point process</em>. If the number of events that occur over time are counted, then the stochastic process is instead known as a <em>counting process</em>. Counting processes form the basis for multi-state models, and linkage to the theory of martingales (not discussed here) provides a theoretical framework for these models.</p>
</section>
<section id="markov-process" class="level3">
<h3 class="anchored" data-anchor-id="markov-process">Markov process</h3>
<p>A stochastic process is called a ‘Markov process’ if the future state of a process depends only on the present state, and not on the sequence of events that preceded it. Equivalently, for a Markov process the conditional probability of a future state <img src="https://latex.codecogs.com/png.latex?X(t_%7Bi+j%7D)"> given <img src="https://latex.codecogs.com/png.latex?X(t_i)"> is independent of previous states <img src="https://latex.codecogs.com/png.latex?X(t_0),%20X(t_1),%20%5Cdots,%20X(t_%7Bi-1%7D)">.</p>
</section>
<section id="time-homogeneous-markov-processes" class="level3">
<h3 class="anchored" data-anchor-id="time-homogeneous-markov-processes">Time-homogeneous Markov processes</h3>
<p>Markov processes are said to be ‘time-homogeneous’ if the probability of transition from one state to the next (termed the <em>transition probability</em>) is independent of the time parameter <img src="https://latex.codecogs.com/png.latex?t">. Equivalently, for <img src="https://latex.codecogs.com/png.latex?%5CPr(X(t%20+%20u)%20=%20s%20%5Cmid%20X(t)%20=%20r)"> denoting the conditional probability of a process <img src="https://latex.codecogs.com/png.latex?X(%5Ccdot)"> being in state <img src="https://latex.codecogs.com/png.latex?s"> at time <img src="https://latex.codecogs.com/png.latex?t%20+%20u">, given the process was in state <img src="https://latex.codecogs.com/png.latex?r"> at time <img src="https://latex.codecogs.com/png.latex?t">, a Markov process is time-homogeneous if:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5CPr(X(t+u)%20=%20s%20%5Cmid%20X(t)%20=%20r)%20=%20%5CPr(X(u)%20=%20s%20%5Cmid%20X(0)%20=%20r)%0A"></p>
<p>A well-known time-homogeneous Markov counting process is the Poisson process, where events occur randomly and independently of each other. A homogeneous Poisson process is described by its constant intensity parameter <img src="https://latex.codecogs.com/png.latex?%5Clambda%20%3E%200">, which represents the average rate of events that occur per unit time. For any infinitesimal time interval <img src="https://latex.codecogs.com/png.latex?%5Bt,%20t+%5Cdelta%5D">, as <img src="https://latex.codecogs.com/png.latex?%5Cdelta%20%5Crightarrow%200">, the probability of exactly one event occurring in this interval is asymptotically <img src="https://latex.codecogs.com/png.latex?%5Clambda%5Cdelta">.</p>
</section>
<section id="multi-state-processes" class="level3">
<h3 class="anchored" data-anchor-id="multi-state-processes">Multi-state processes</h3>
<p>Multi-state processes are discrete-state stochastic processes with a finite state space <img src="https://latex.codecogs.com/png.latex?%5Cmathcal%7BS%7D%20=%20%5C%7B1,%202,%20%5Cldots,%20m%5C%7D">. In these processes, an individual begins in one state and spends a random, continuously-distributed time in that state before moving to a random next state. Multi-state processes are defined by the initial distribution of the states <img src="https://latex.codecogs.com/png.latex?%5CPr(X(0)%20=%20r)">, and the transition probabilities <img src="https://latex.codecogs.com/png.latex?%5CPr(X(t%20+%20u)%20=%20s%20%5Cmid%20X(t)%20=%20r,%20%5Cmathcal%7BX%7D_t)"> from state <img src="https://latex.codecogs.com/png.latex?r"> to state <img src="https://latex.codecogs.com/png.latex?s"> during the interval <img src="https://latex.codecogs.com/png.latex?(t,%20t%20+%20u%5D">, with <img src="https://latex.codecogs.com/png.latex?r,s%20%5Cin%20%5Cmathcal%7BS%7D">, and where <img src="https://latex.codecogs.com/png.latex?%5Cmathcal%7BX%7D_t"> represents the history of the process <img src="https://latex.codecogs.com/png.latex?X(%5Ccdot)"> up to time <img src="https://latex.codecogs.com/png.latex?t">.</p>
<p>Figure&nbsp;1 shows how a counting process may be built on top of a multi-state process: panel A shows a multi-state process with transitions between two states, and the corresponding counting process for the transition event from State 1 <img src="https://latex.codecogs.com/png.latex?%5Crightarrow"> State 2 is shown in panel B.</p>
<div id="fig-counting-process" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-counting-process-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell">
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.pkirwan.com/blog/multi-state-models/index_files/figure-html/unnamed-chunk-2-1.png" class="img-fluid figure-img" alt="Two panels. Panel A shows a process which starts in state 1, moves to state 2 at time t1, returns to state 1, moves to state 2 again at time t2 and returns to state 1. Panel B shows the corresponding counting process of 1 to 2 transitions, which steps up from 0 to 1 at time t1 and from 1 to 2 at time t2." width="672"></p>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-counting-process-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;1: Example of transitions between two states in a multi-state process (panel A), and the corresponding counting process for the State 1 → State 2 transition (panel B).
</figcaption>
</figure>
</div>
</section>
</section>
<section id="multi-state-models" class="level2">
<h2 class="anchored" data-anchor-id="multi-state-models">Multi-state models</h2>
<p>In a multi-state model, each state represents a different stage or condition that an individual may experience. The transitions between these states are modelled as a multi-state process, with the time spent in each state and the transitions between states being random variables that can be estimated from data.</p>
<p>Multi-state models are particularly useful in the context of disease progression, as each state in the model can be used to represent a different level of disease severity, with transitions between states representing progression. This may allow for a more nuanced understanding of disease processes, capturing the different pathways that patients may experience.</p>
</section>
<section id="continuous-time-msms" class="level2">
<h2 class="anchored" data-anchor-id="continuous-time-msms">Continuous-time multi-state models</h2>
<div class="cell">
<div class="cell-output-display">
<div id="fig-msm" class="quarto-float quarto-figure quarto-figure-center anchored" alt="Diagram of three boxes labelled State 1, State 2 and State 3. Arrows labelled q 1,2 and q 2,1 join State 1 and State 2 in both directions. Arrows labelled q 1,3 and q 2,3 lead from State 1 and State 2 to State 3.">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-msm-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://www.pkirwan.com/blog/multi-state-models/index_files/figure-html/fig-msm-1.png" class="img-fluid figure-img" alt="Diagram of three boxes labelled State 1, State 2 and State 3. Arrows labelled q 1,2 and q 2,1 join State 1 and State 2 in both directions. Arrows labelled q 1,3 and q 2,3 lead from State 1 and State 2 to State 3." width="480">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-msm-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;2: Example of a three-state model with transitions between states according to transition intensities <img src="https://latex.codecogs.com/png.latex?%5C%7Bq_%7Br,s%7D%20:%20r,s%20%5Cin%20(1,2,3)%5C%7D">
</figcaption>
</figure>
</div>
</div>
</div>
<p>Continuous-time multi-state models are defined by transition intensities, <img src="https://latex.codecogs.com/png.latex?q_%7Br,s%7D(t,%0A%5Cboldsymbol%7Bz%7D(t))">, which represent the instantaneous hazard of moving from state <img src="https://latex.codecogs.com/png.latex?r"> to state <img src="https://latex.codecogs.com/png.latex?s%20%5Cneq%20r"> at time <img src="https://latex.codecogs.com/png.latex?t">, dependent on a set of explanatory, potentially time-varying, covariates <img src="https://latex.codecogs.com/png.latex?%5Cboldsymbol%7Bz%7D(t)">. Defining an individual’s state at time <img src="https://latex.codecogs.com/png.latex?t"> as <img src="https://latex.codecogs.com/png.latex?X(t)"> then:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0Aq_%7Br,s%7D(t,%20%5Cboldsymbol%7Bz%7D(t))%20=%20%5Clim_%7B%5Cdelta%20t%5Cdownarrow%200%7D%5Cfrac%7B%5CPr(X(t+%5Cdelta%20t)=s%20%5Cmid%20X(t)=r,%20%5Cboldsymbol%7Bz%7D(t))%7D%7B%5Cdelta%20t%7D%0A"></p>
<p>From <a href="../../blog/survival-analysis/index.html#hazard-function">the definition of the hazard function</a>, this transition intensity is equivalent to the hazard of transition from one state to another. These transition intensities form a <em>transition intensity matrix</em> <img src="https://latex.codecogs.com/png.latex?%5Cmathbf%7BQ%7D">, whose rows sum to zero, with diagonal entries defined by:</p>
<p><img src="https://latex.codecogs.com/png.latex?q_%7Br,r%7D(t,%20%5Cboldsymbol%7Bz%7D(t))%20=%20-%20%5Csum_%7Bs%20%5Cneq%20r%7D%20q_%7Br,s%7D(t,%20%5Cboldsymbol%7Bz%7D(t))"></p>
<p>For the example three-state model shown in Figure&nbsp;2 this matrix would be:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Cmathbf%7BQ%7D%20=%20%5Cbegin%7Bbmatrix%7D%0A-q_%7B1,2%7D-q_%7B1,3%7D%20&amp;%20q_%7B1,2%7D%20&amp;%20q_%7B1,3%7D%20%5C%5C%0Aq_%7B2,1%7D%20&amp;%20-q_%7B2,1%7D-q_%7B2,3%7D%20&amp;%20q_%7B2,3%7D%20%5C%5C%0A0%20&amp;%200%20&amp;%200%20%5C%5C%0A%5Cend%7Bbmatrix%7D%0A"></p>
<p>Here, state 3 is known as an ‘absorbing’ state, as individuals do not leave the state after arrival, while states 1 and 2 are ‘transient’ states. For a time-homogeneous model, where the transition intensities do not depend on time, the <em>transition probability matrix</em>, which contains the probabilities of moving between states within a time-interval of length <img src="https://latex.codecogs.com/png.latex?t"> is derived from the transition intensity matrix by the matrix exponential:</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cmathbf%7BP%7D(t)%20=%20%5Cexp(t%5Cmathbf%7BQ%7D)%20=%20%5Csum_%7Bn=0%7D%5E%7B%5Cinfty%7D%5Cfrac%7Bt%5En%7D%7Bn!%7D%5Cmathbf%7BQ%7D%5En"></p>
<p>When the transition intensities do depend on time, there is no closed-form matrix exponential, and the transition probabilities are instead obtained by a product integral of the intensity matrix (see the Aalen-Johansen estimator in the next post).</p>
<section id="covariates" class="level3">
<h3 class="anchored" data-anchor-id="covariates">Covariates</h3>
<p>The (potentially time-varying) effect of a given set of <img src="https://latex.codecogs.com/png.latex?M"> covariates, <img src="https://latex.codecogs.com/png.latex?%5Cboldsymbol%7Bz%7D(t)%20=%20%5C%7Bz_1(t),%20%5Cldots,%20z_M(t)%5C%7D">, on the transition intensities <img src="https://latex.codecogs.com/png.latex?q_%7Br,s%7D(t,%20%5Cboldsymbol%7Bz%7D(t))"> can be expressed via a proportional hazards regression model. Typically these combine a parametric baseline hazard, <img src="https://latex.codecogs.com/png.latex?q%5E%7B(0)%7D_%7Br,s%7D(t)">, with log-linear regression:</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cbegin%7Balign*%7D%0Aq_%7Br,s%7D(t,%20%5Cboldsymbol%7Bz%7D(t))%20&amp;%20=%20q%5E%7B(0)%7D_%7Br,s%7D(t)%5Cexp%5Cleft(%5Csum_%7Bm=1%7D%5E%7BM%7D%5Cbeta_%7Br,s,m%7Dz_%7Bm%7D(t)%5Cright)%20%5C%5C%0A&amp;%20=%20q%5E%7B(0)%7D_%7Br,s%7D(t)%5Cexp%5Cleft(%5Cboldsymbol%7B%5Cbeta%7D_%7Br,s%7D%5E%5Cmathsf%7BT%7D%5Cboldsymbol%7Bz%7D(t)%5Cright)%0A%5Cend%7Balign*%7D"></p>
<p>where <img src="https://latex.codecogs.com/png.latex?%5Cexp(%5Cbeta_%7Br,s,m%7D)"> is the hazard ratio for the <img src="https://latex.codecogs.com/png.latex?m">th covariate on the <img src="https://latex.codecogs.com/png.latex?r%20%5Crightarrow%20s"> transition.</p>
</section>
<section id="sojourn-time" class="level3">
<h3 class="anchored" data-anchor-id="sojourn-time">Sojourn time</h3>
<p>The time spent in a state prior to transition is termed the <em>sojourn time</em>. In the case of a time-homogeneous Markov model, the mean sojourn time in state <img src="https://latex.codecogs.com/png.latex?r">, <img src="https://latex.codecogs.com/png.latex?W_r">, is the inverse of the transition intensity for leaving the state:</p>
<p><img src="https://latex.codecogs.com/png.latex?E(W_r)%20=%20-%5Cfrac%7B1%7D%7Bq_%7Br,r%7D%7D"></p>
</section>
<section id="r-example-msm" class="level3">
<h3 class="anchored" data-anchor-id="r-example-msm">R example</h3>
<p>The <code>msm</code> package can be used to fit continuous-time Markov multi-state models. The <code>cav</code> dataset included in the package contains serial examinations of heart transplant recipients, with states <img src="https://latex.codecogs.com/png.latex?1"> = no coronary allograft vasculopathy (CAV), <img src="https://latex.codecogs.com/png.latex?2"> = mild/moderate CAV, <img src="https://latex.codecogs.com/png.latex?3"> = severe CAV, and <img src="https://latex.codecogs.com/png.latex?4"> = death. Patients were only examined at intermittent clinic visits, so the times of transitions between the first three states are interval-censored, whereas the time of death is known exactly (<code>deathexact = 4</code>). The code below fits a model with a constant intensity for each allowed transition, with non-zero entries of the initial matrix indicating which transitions are allowed.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" data-lst-cap="Fitting a continuous-time multi-state model to the cav data using the msm package." style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb1-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(msm)</span>
<span id="cb1-2"></span>
<span id="cb1-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Allowed transitions have non-zero starting values for the intensities</span></span>
<span id="cb1-4">Q_init <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rbind</span>(</span>
<span id="cb1-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>,     <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.25</span>,  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>,     <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.25</span>),</span>
<span id="cb1-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.166</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>,     <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.166</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.166</span>),</span>
<span id="cb1-7">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>,     <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.25</span>,  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>,     <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.25</span>),</span>
<span id="cb1-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>,     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>,     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>,     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span>
<span id="cb1-9">)</span>
<span id="cb1-10"></span>
<span id="cb1-11">cav_fit <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">msm</span>(</span>
<span id="cb1-12">  state <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> years, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">subject =</span> PTNUM, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> cav,</span>
<span id="cb1-13">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">qmatrix =</span> Q_init, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">deathexact =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span></span>
<span id="cb1-14">)</span>
<span id="cb1-15"></span>
<span id="cb1-16"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">qmatrix.msm</span>(cav_fit)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>estimates, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>        State 1 State 2 State 3 State 4
State 1  -0.170   0.128   0.000   0.043
State 2   0.225  -0.608   0.343   0.040
State 3   0.000   0.131  -0.437   0.306
State 4   0.000   0.000   0.000   0.000</code></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" data-lst-cap="Fitting a continuous-time multi-state model to the cav data using the msm package." style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb3-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sojourn.msm</span>(cav_fit)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>        estimates        SE        L        U
State 1  5.869552 0.3307930 5.255734 6.555057
State 2  1.644897 0.1288274 1.410825 1.917805
State 3  2.287819 0.2743666 1.808595 2.894023</code></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb5" data-lst-cap="Fitting a continuous-time multi-state model to the cav data using the msm package." style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb5-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pmatrix.msm</span>(cav_fit, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">t =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>), <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>        State 1 State 2 State 3 State 4
State 1   0.520   0.139   0.091   0.251
State 2   0.244   0.139   0.181   0.436
State 3   0.061   0.069   0.169   0.701
State 4   0.000   0.000   0.000   1.000</code></pre>
</div>
</div>
<p>The first output is the estimated transition intensity matrix <img src="https://latex.codecogs.com/png.latex?%5Cmathbf%7BQ%7D">, with rows summing to zero. The mean sojourn times are the inverse of the negative diagonal entries, giving an estimated mean time of 5.9 years in state 1 before a transition. The final output is the transition probability matrix <img src="https://latex.codecogs.com/png.latex?%5Cmathbf%7BP%7D(5)">, for example the probability of a patient who is in state 1 now being in state 4 (dead) after 5 years is estimated to be 0.25.</p>
</section>
</section>
<section id="discrete-time-msms" class="level2">
<h2 class="anchored" data-anchor-id="discrete-time-msms">Discrete-time multi-state models</h2>
<p>For population studies which measure duration in discrete time, discrete-time multi-state models may be applied. Since the concept of instantaneous risk does not apply in discrete time, transition probabilities are instead defined which represent the probability of transition from state <img src="https://latex.codecogs.com/png.latex?r"> to state <img src="https://latex.codecogs.com/png.latex?s"> in the time interval <img src="https://latex.codecogs.com/png.latex?(t_i,t_j%5D">, <img src="https://latex.codecogs.com/png.latex?t_j%3Et_i">:</p>
<p><img src="https://latex.codecogs.com/png.latex?p_%7Br,s%7D(t_i,%20t_j)%20=%20%5CPr(X(t_j)%20=%20s%20%5Cmid%20X(t_i)%20=%20r)"></p>
</section>
<section id="semi-hidden" class="level2">
<h2 class="anchored" data-anchor-id="semi-hidden">Semi-Markov and hidden Markov models</h2>
<p>Multi-state models are typically specified to be Markov, i.e.&nbsp;<img src="https://latex.codecogs.com/png.latex?q_%7Br,s%7D(t;%20%5Cmathcal%7BX%7D_t)%20=%20q_%7Br,s%7D(t)">, where <img src="https://latex.codecogs.com/png.latex?%5Cmathcal%7BX%7D_t"> is the observation history of the process up to time <img src="https://latex.codecogs.com/png.latex?t">. Semi-Markov models relax the Markov assumption, allowing dependence on the time of entry into the current state, i.e.&nbsp;<img src="https://latex.codecogs.com/png.latex?q_%7Br,s%7D(t;%5Cmathcal%7BX%7D_t)=q_%7Br,s%7D(t-t_r)">, where <img src="https://latex.codecogs.com/png.latex?t_r"> is the time of entry into the current state <img src="https://latex.codecogs.com/png.latex?r">.</p>
<p>Hidden Markov models may also be specified to allow for unobserved, or ‘latent’, states to be included in the model. These can be particularly useful for modelling complex disease processes, where progression of the disease is influenced by unobserved factors and the time to event depends on the current state of the disease (for instance in models of HIV progression); as well as when the disease state is imperfectly observed (for instance to incorporate measurement error).</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
<span class="screen-reader-only">Note</span>Key takeaways
</div>
</div>
<div class="callout-body-container callout-body">
<ul>
<li>Multi-state models extend standard survival methods by allowing individuals to move between multiple states over time, not just from “alive” to “dead”.</li>
<li>These models are built on stochastic processes theory, particularly Markov processes, where future states depend only on the present state.</li>
<li>Transition intensities (analogous to hazard rates) describe the instantaneous risk of moving from one state to another.</li>
<li>Multi-state models can incorporate covariates to identify factors that influence transition rates between states.</li>
<li>Different model variations (time-homogeneous, semi-Markov, hidden Markov) provide flexibility to model complex disease processes with various assumptions.</li>
<li>Multi-state models can be fitted in R, for example using the <code>msm</code> package.</li>
</ul>
</div>
</div>
</section>
<section id="coming-next" class="level2">
<h2 class="anchored" data-anchor-id="coming-next">Coming next</h2>
<p>In the next post, I’ll discuss statistical inference methods for multi-state models, including non-parametric estimation with the Aalen-Johansen estimator and parametric approaches using maximum likelihood.</p>
</section>
<section id="references" class="level2">
<h2 class="anchored" data-anchor-id="references">References</h2>
<ul>
<li>Aalen O, Borgan O, Gjessing H. <a href="https://play.google.com/store/books/details?id=2toprArSUMAC">Survival and Event History Analysis: A Process Point of View</a>. <em>Springer</em>; 2008. 540 p.</li>
<li>Andersen PK, Borgan O, Gill RD, Keiding N. <a href="http://dx.doi.org/10.1007/978-1-4612-4348-9">Statistical models based on counting processes</a>. <em>Springer</em>; 1996. 784 p.</li>
<li>Andersen PK, Keiding N. <a href="http://dx.doi.org/10.1191/0962280202SM276ra">Multi-state models for event history analysis</a>. <em>Stat Methods Med Res</em>. 2002;11(2):91-115.</li>
<li>Chiang CL. An introduction to stochastic processes and their applications. <em>RE Krieger</em>; 1980.</li>
<li>Jackson CH. <a href="https://doi.org/10.18637/jss.v038.i08">Multi-state models for panel data: the msm package for R</a>. <em>J Stat Softw</em>. 2011;38(8):1-28.</li>
<li>Putter H, Fiocco M, Geskus RB. <a href="http://dx.doi.org/10.1002/sim.2712">Tutorial in biostatistics: competing risks and multi-state models</a>. <em>Stat Med</em>. 2007;26(11):2389-430.</li>
<li>van den Hout A. <a href="https://doi.org/10.1201/9781315374321">Multi-State Survival Models for Interval-Censored Data</a>. <em>CRC Press</em>; 2016. 238 p.</li>
</ul>
<div class="post-navigation">
<p><a href="../../blog/competing-risks-methods/index.html">← Previous post</a></p>
<p><a href="../../index.html#blog">Back to all posts</a></p>
<p><a href="../../blog/statistical-inference-msms/index.html">Next post →</a></p>
</div>


</section>

<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-reuse"><h2 class="anchored quarto-appendix-heading">Reuse</h2><div class="quarto-appendix-contents"><div><a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a></div></div></section><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre class="sourceCode code-with-copy quarto-appendix-bibtex"><code class="sourceCode bibtex">@online{kirwan2025,
  author = {Kirwan, Peter},
  title = {Part {V:} {Multi-state} Models},
  date = {2025-09-23},
  url = {https://www.pkirwan.com/blog/multi-state-models/},
  langid = {en}
}
</code></pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-kirwan2025" class="csl-entry quarto-appendix-citeas">
Kirwan, Peter. 2025. <span>“Part V: Multi-State Models.”</span>
September 23. <a href="https://www.pkirwan.com/blog/multi-state-models/">https://www.pkirwan.com/blog/multi-state-models/</a>.
</div></div></section></div> ]]></description>
  <category>Transition intensity</category>
  <category>Markov property</category>
  <guid>https://www.pkirwan.com/blog/multi-state-models/</guid>
  <pubDate>Tue, 23 Sep 2025 00:00:00 GMT</pubDate>
  <media:content url="https://www.pkirwan.com/blog/multi-state-models/multi-state-models-banner.png" medium="image" type="image/png" height="80" width="144"/>
</item>
<item>
  <title>Part IV: Competing risks survival methods</title>
  <dc:creator>Peter Kirwan</dc:creator>
  <link>https://www.pkirwan.com/blog/competing-risks-methods/</link>
  <description><![CDATA[ 






<p>This is part four of a series on statistical methods for infectious disease epidemiology, with a focus on time-to-event, or “survival”, data.</p>
<section id="competing-risks" class="level2">
<h2 class="anchored" data-anchor-id="competing-risks">Competing risks</h2>
<p>In medical cohort studies, multiple study end-points are common (e.g.&nbsp;death and discharge from hospital). These multiple end-points are known as <em>competing risks</em> and may prevent observation of the event of interest or alter its probability. Treating competing events as ordinary censoring can be problematic when the aim is to estimate the probability of a specific event over time. In particular, the Kaplan-Meier estimator will typically overestimate this probability. Cause-specific Cox models remain useful for modelling cause-specific hazards, but they do not directly estimate the cumulative incidence function in the presence of competing risks.</p>
<p>Note that not every event is a competing risk. An intermediate event, such as admission to intensive care, can be followed by death or discharge, so does not prevent observation of these events. Processes with intermediate events are instead described by <em>multi-state models</em>, which are the subject of the next post.</p>
<div class="cell">
<div class="cell-output-display">
<div id="fig-competing-risks" class="quarto-float quarto-figure quarto-figure-center anchored" alt="Diagram with a box labelled Hospital and arrows leading to two boxes, Discharged and Died.">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-competing-risks-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://www.pkirwan.com/blog/competing-risks-methods/index_files/figure-html/fig-competing-risks-1.png" class="img-fluid figure-img" alt="Diagram with a box labelled Hospital and arrows leading to two boxes, Discharged and Died." width="480">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-competing-risks-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;1: An example of competing risks in survival data. In this scenario, patients admitted to hospital can experience one of two outcomes: death or discharge. Each outcome “competes” with the other, and experiencing one prevents the observation of the other.
</figcaption>
</figure>
</div>
</div>
</div>
<p>To correctly address competing risks, “competing risks survival models” are available. In these models an individual is observed over time, with several possible events ‘competing’ until one takes place and the individual transitions to the corresponding state. Importantly, these methods do not require an assumption of independence between the times to the competing events, and censoring can still be appropriately accounted for (provided it is independent of the event process).</p>
</section>
<section id="cause-specific-functions" class="level2">
<h2 class="anchored" data-anchor-id="cause-specific-functions">Cause-specific survival functions</h2>
<p>We’ll start by defining the cause-specific hazard and cause-specific cumulative incidence functions, which are the key components of competing risks survival analysis.</p>
<section id="cause-specific-hazards" class="level3">
<h3 class="anchored" data-anchor-id="cause-specific-hazards">Cause-specific hazard function</h3>
<p>Let <img src="https://latex.codecogs.com/png.latex?T"> be a random variable for the survival time and <img src="https://latex.codecogs.com/png.latex?C"> be a random variable for the cause of failure. The <em>cause-specific</em> hazard function for the <img src="https://latex.codecogs.com/png.latex?j">th cause, <img src="https://latex.codecogs.com/png.latex?j%20=%20%5C%7B1,%202,%20%5Cldots,%20m%5C%7D"> is defined by:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0Ah_j(t)%20=%20%5Clim_%7B%5Cdelta%20t%20%5Cdownarrow%200%7D%20%5Cfrac%7B%5CPr(t%20%5Cleq%20T%20%3C%20t%20+%20%5Cdelta%20t,%20C=j%20%5Cmid%20T%20%5Cgeq%20t)%7D%7B%5Cdelta%20t%7D%0A"></p>
<p>Defining <img src="https://latex.codecogs.com/png.latex?f_j(t)"> as the <em>cause-specific</em> density function, and <img src="https://latex.codecogs.com/png.latex?S(t)=%5CPr(T%20%5Cgeq%20t)"> as the overall survivor function, the relationship shown in <a href="../../blog/survival-analysis/index.html#hazard-function">part II of this series</a> still holds in the presence of competing risks:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0Ah_j(t)=%5Cfrac%7Bf_j(t)%7D%7BS(t)%7D%0A"></p>
</section>
<section id="cause-specific-cumulative-incidence" class="level3">
<h3 class="anchored" data-anchor-id="cause-specific-cumulative-incidence">Cause-specific cumulative incidence</h3>
<p>The <em>cause-specific</em> cumulative incidence function, i.e.&nbsp;the probability of failure from cause <img src="https://latex.codecogs.com/png.latex?j"> before time <img src="https://latex.codecogs.com/png.latex?t">, in the presence of all other risks, is given by:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0AF_j(t)%20=%20%5CPr(T%20%3C%20t,%20C=j)%0A"></p>
<p>for <img src="https://latex.codecogs.com/png.latex?j=%5C%7B1,%202,%20%5Cdots,%20m%5C%7D">, with <img src="https://latex.codecogs.com/png.latex?%5CPr(C=j)"> often written as <img src="https://latex.codecogs.com/png.latex?%5Cpi_j">.</p>
<p>An expression for <img src="https://latex.codecogs.com/png.latex?F_j(t)"> in terms of the cause-specific hazard function may be derived using the equation above:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Cbegin%7Baligned%7D%0Ah_j(t)%20&amp;=%5Cfrac%7Bf_j(t)%7D%7BS(t)%7D%20%5C%5C%0Af_j(t)%20&amp;=S(t)h_j(t)%20%5C%5C%0AF_j(t)%20&amp;=%5Cint_0%5Et%20S(u)h_j(u)%20du%0A%5Cend%7Baligned%7D%0A"></p>
</section>
</section>
<section id="aalen-johansen" class="level2">
<h2 class="anchored" data-anchor-id="aalen-johansen">Aalen-Johansen estimator</h2>
<p>The standard non-parametric estimator of the cause-specific incidence function is the Aalen-Johansen estimator, also described as the ‘multi-state version’ of the Kaplan-Meier estimator.</p>
<p>The Aalen-Johansen estimator is built from the non-parametric Nelson-Aalen estimator of the cause-specific hazard function for cause <img src="https://latex.codecogs.com/png.latex?j">, which has increments:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Chat%7Bh%7D_j(t)%20=%20%5Cfrac%7Bd_%7Bj%7D(t)%7D%7Bn(t%5Cmbox%7B-%7D)%7D%0A"></p>
<p>where <img src="https://latex.codecogs.com/png.latex?d_%7Bj%7D(t)"> is the number of events due to cause <img src="https://latex.codecogs.com/png.latex?j"> at time <img src="https://latex.codecogs.com/png.latex?t">, and <img src="https://latex.codecogs.com/png.latex?n(t%5Cmbox%7B-%7D)"> is the number of individuals at risk just prior to <img src="https://latex.codecogs.com/png.latex?t">.</p>
<p>With the Kaplan-Meier estimate of the survivor function defined in <a href="../../blog/classical-survival-methods/index.html#kaplan-meier">part III of this series</a>, <img src="https://latex.codecogs.com/png.latex?%5Chat%7BS%7D(t)">, the Aalen-Johansen estimator for the cause-specific cumulative incidence function then follows from the equation above:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Chat%7BF%7D_j(t)%20=%20%5Csum_%7Bt_k%20%5Cleq%20t%7D%20%5Chat%7BS%7D(t_%7Bk-1%7D)%5Cfrac%7Bd_%7Bj%7D(t_k)%7D%7Bn(t_k%5Cmbox%7B-%7D)%7D%0A"></p>
<p>for all times <img src="https://latex.codecogs.com/png.latex?t_k%20%5Cleq%20t"> where transition events are observed to occur.</p>
<p>The choice between cause-specific hazards and cumulative incidence depends on the research question. Cause-specific hazards are often preferred for <em>aetiological</em> questions about how a covariate affects the instantaneous rate of a given event. Cumulative incidence, and regression models such as Fine-Gray, are often preferred when the aim is to estimate or predict the <em>absolute risk</em> of a given event over time in the presence of competing risks.</p>
<section id="r-example-aj" class="level3">
<h3 class="anchored" data-anchor-id="r-example-aj">R example</h3>
<p>We can illustrate the difference between the naive Kaplan-Meier estimate and the Aalen-Johansen estimator for cumulative incidence in a simple example. Consider a dataset of 10 patients with follow-up times and event types (death, discharge, or censoring):</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" data-lst-cap="Comparing naive and Aalen-Johansen cumulative incidence estimates in R." style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb1-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(survival)</span>
<span id="cb1-2"></span>
<span id="cb1-3">cr_data <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">data.frame</span>(</span>
<span id="cb1-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">time   =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>( <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>,    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>,    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>,      <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>,     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>,</span>
<span id="cb1-5">              <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>,    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>,    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span>,     <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>,    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11</span>),</span>
<span id="cb1-6">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">status =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"death"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"discharge"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"censor"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"death"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"discharge"</span>,</span>
<span id="cb1-7">             <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"death"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"censor"</span>,    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"discharge"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"death"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"censor"</span>)</span>
<span id="cb1-8">)</span>
<span id="cb1-9"></span>
<span id="cb1-10"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Naive estimate: treat discharge as ordinary censoring</span></span>
<span id="cb1-11">km_fit <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">survfit</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Surv</span>(time, status <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"death"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> cr_data)</span>
<span id="cb1-12"></span>
<span id="cb1-13"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Aalen-Johansen: with a multi-state outcome, survfit() returns the estimated</span></span>
<span id="cb1-14"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># probability of being in each state; the first level is censoring</span></span>
<span id="cb1-15">aj_fit <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">survfit</span>(</span>
<span id="cb1-16">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Surv</span>(time, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">factor</span>(status, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">levels =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"censor"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"death"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"discharge"</span>))) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,</span>
<span id="cb1-17">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> cr_data</span>
<span id="cb1-18">)</span>
<span id="cb1-19"></span>
<span id="cb1-20">cif_df <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">data.frame</span>(</span>
<span id="cb1-21">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">time   =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, aj_fit<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>time),</span>
<span id="cb1-22">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">cif_aj =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, aj_fit<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>pstate[, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"death"</span>]),</span>
<span id="cb1-23">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">cif_km =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summary</span>(km_fit, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">times =</span> aj_fit<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>time, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">extend =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>surv)</span>
<span id="cb1-24">)</span>
<span id="cb1-25"></span>
<span id="cb1-26"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(cif_df, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>   time cif_aj cif_km
1     0   0.00   0.00
2     2   0.10   0.10
3     3   0.10   0.10
4     4   0.10   0.10
5     5   0.21   0.23
6     6   0.21   0.23
7     7   0.33   0.38
8     8   0.33   0.38
9     9   0.33   0.38
10   10   0.48   0.69
11   11   0.48   0.69</code></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" data-lst-cap="Comparing naive and Aalen-Johansen cumulative incidence estimates in R." style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb3-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(cif_df, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> time)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb3-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_step</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> cif_km, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">colour =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Naive (1 - KM)"</span>), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">linewidth =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.1</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb3-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_step</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> cif_aj, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">colour =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Aalen-Johansen"</span>), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">linewidth =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.1</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb3-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_colour_manual</span>(</span>
<span id="cb3-5">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(</span>
<span id="cb3-6">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Naive (1 - KM)"</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> blog_cols[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"dark"</span>]],</span>
<span id="cb3-7">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Aalen-Johansen"</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> blog_cols[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"red"</span>]]</span>
<span id="cb3-8">    )</span>
<span id="cb3-9">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb3-10">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_y_continuous</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">limits =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">NA</span>), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">name =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Cumulative incidence of death"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb3-11">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_x_continuous</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">name =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Follow-up time"</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.pkirwan.com/blog/competing-risks-methods/index_files/figure-html/lst-competing-risk-cif-1.png" class="img-fluid figure-img" alt="Step plot of cumulative incidence of death over follow-up time. The naive one minus Kaplan-Meier curve lies above the Aalen-Johansen curve, reaching about 0.69 compared with about 0.48 at the end of follow-up." width="672"></p>
</figure>
</div>
</div>
</div>
<p>The Aalen-Johansen estimate is equivalent to the sum <img src="https://latex.codecogs.com/png.latex?%5Chat%7BF%7D_j(t)%20=%20%5Csum_%7Bt_k%20%5Cleq%20t%7D%20%5Chat%7BS%7D(t_%7Bk-1%7D)%5C,%20d_%7Bj%7D(t_k)/n(t_k%5Cmbox%7B-%7D)"> given above, where <img src="https://latex.codecogs.com/png.latex?%5Chat%7BS%7D"> is the Kaplan-Meier estimate of surviving all causes. Other packages, such as <code>cmprsk</code> and <code>tidycmprsk</code>, also provide cumulative incidence estimates and Fine-Gray regression.</p>
<p>The naive curve lies above the Aalen-Johansen estimate because discharge is handled as if it were non-informative censoring, even though it removes patients from ever experiencing the event of interest.</p>
</section>
</section>
<section id="fine-gray" class="level2">
<h2 class="anchored" data-anchor-id="fine-gray">Fine-Gray proportional hazards model</h2>
<p>Analogous to the Cox proportional hazards model described in <a href="../../blog/classical-survival-methods/index.html">the last post</a>, the Fine-Gray proportional hazards model may be used to estimate the hazard of the event of interest (termed the sub-distribution hazard) among those yet to experience that event by time <img src="https://latex.codecogs.com/png.latex?t">. The risk set for the sub-distribution hazard consists of both those who have yet to experience any event, and those who have already experienced a competing event (who remain in the risk set).</p>
<section id="sub-distribution-hazard" class="level3">
<h3 class="anchored" data-anchor-id="sub-distribution-hazard">Sub-distribution hazard</h3>
<p>The sub-distribution hazard is therefore defined as the instantaneous risk of experiencing the event of interest <img src="https://latex.codecogs.com/png.latex?j"> given that the individual has not already experienced this event:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Clambda_j(t)=%5Clim_%7B%5Cdelta%20t%20%5Cdownarrow%200%7D%7B%5Cfrac%7B%5CPr%5Cleft(t%20%5Cleq%20T%20%3C%20t%20+%20%5Cdelta%20t,%20C=j%20%5Cmid%20T%3Et%20%5Ctext%7B%20or%7D%20%5Cleft(T%20%5Cle%20t,%20C%20%5Cneq%20j%5Cright)%5Cright)%7D%7B%5Cdelta%20t%7D%7D%0A"></p>
<p>where, as before, <img src="https://latex.codecogs.com/png.latex?C"> is the random variable for the event that occurs.</p>
</section>
<section id="fine-gray-regression" class="level3">
<h3 class="anchored" data-anchor-id="fine-gray-regression">Fine-Gray regression model</h3>
<p>Fine-Gray regression links the sub-distribution hazard, <img src="https://latex.codecogs.com/png.latex?%5Clambda_%7Bj%7D">, to the cause-specific cumulative incidence function, <img src="https://latex.codecogs.com/png.latex?F_%7Bj%7D">, through the relationship:</p>
<p><img src="https://latex.codecogs.com/png.latex?%20%5Clambda_%7Bj%7D(t)%20=%20-%20%5Cfrac%7Bd%7D%7Bdt%7D%20%5Clog%7B(1-F_%7Bj%7D(t))%7D%20"></p>
<p>As with the Cox proportional hazards model, a proportional hazards regression model is assumed, where the hazard of cause <img src="https://latex.codecogs.com/png.latex?j"> at time <img src="https://latex.codecogs.com/png.latex?t"> for individual <img src="https://latex.codecogs.com/png.latex?i"> is:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Clambda_%7Bi,j%7D(t)%20=%20%5Cexp(%5Cboldsymbol%7B%5Cbeta%7D%5E%5Cmathsf%7BT%7D%5Cboldsymbol%7Bz%7D_i)%5Clambda%5E%7B(0)%7D_%7Bj%7D(t)%0A"></p>
<p>with <img src="https://latex.codecogs.com/png.latex?%5Clambda%5E%7B(0)%7D_%7Bj%7D(t)"> being the baseline sub-distribution hazard for cause <img src="https://latex.codecogs.com/png.latex?j">. Covariate coefficients are estimated by maximising the weighted partial likelihood <img src="https://latex.codecogs.com/png.latex?L(%5Cboldsymbol%7B%5Cbeta%7D)">:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0AL(%5Cboldsymbol%7B%5Cbeta%7D)%20=%20%5Cprod_%7Bi%20%5Cin%0A%5Cmathcal%7BE%7D%7D%5Cfrac%7B%5Cexp(%5Cboldsymbol%7B%5Cbeta%7D%5E%5Cmathsf%7BT%7D%5Cboldsymbol%7Bz%7D_%7Bd_i%7D)%7D%7B%5Csum_%7B%5Cell%20%5Cin%0AR_i%7Dw_%7Bi,%5Cell%7D%5Cexp(%5Cboldsymbol%7B%5Cbeta%7D%5E%5Cmathsf%7BT%7D%5Cboldsymbol%7Bz%7D_%5Cell)%7D%0A"></p>
<p>where <img src="https://latex.codecogs.com/png.latex?w_%7Bi,%5Cell%7D"> are inverse probability of censoring weights, which down-weight individuals who have experienced a competing event to account for the probability that they would have been censored had they remained under follow-up, <img src="https://latex.codecogs.com/png.latex?%5Cmathcal%7BE%7D%20=%20%5C%7BT_1,%20T_2,%20%5Cldots,%20T_n%5C%7D"> are the set of distinct failure times, <img src="https://latex.codecogs.com/png.latex?R_i"> is the set of all individuals who are at risk of failure immediately before time <img src="https://latex.codecogs.com/png.latex?T_i"> (including those who have experienced a competing event), <img src="https://latex.codecogs.com/png.latex?%5Cboldsymbol%7Bz%7D_%7Bd_i%7D"> is the covariate vector for an individual who failed at time <img src="https://latex.codecogs.com/png.latex?T_i">, and <img src="https://latex.codecogs.com/png.latex?%5Cboldsymbol%7Bz%7D_%5Cell"> is the covariate vector for the <img src="https://latex.codecogs.com/png.latex?%5Cell">th individual at risk at time <img src="https://latex.codecogs.com/png.latex?T_i">. Covariate effects on the sub-distribution hazard may be interpreted as covariate effects on the cumulative incidence of the event of interest.</p>
</section>
</section>
<section id="stratification" class="level2">
<h2 class="anchored" data-anchor-id="stratification">Stratification</h2>
<p>Whilst proportional hazards models are a common method for incorporating covariates in survival analyses, a more straightforward approach is through stratification. In a stratified model the population is subdivided according to covariate group (or strata), the survival is compared within each stratum, and the differences within stratum are combined to give an overall comparison.</p>
<p>As stratification allows the baseline hazard to vary across strata it is sometimes used to accommodate non-proportional hazards in Cox and Fine-Gray proportional hazards. Note that the effect of the stratifying variable itself is not estimated, so stratification is most useful for variables which are not of direct interest.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
<span class="screen-reader-only">Note</span>Key takeaways
</div>
</div>
<div class="callout-body-container callout-body">
<ul>
<li>Competing risks occur when individuals can experience multiple possible events that prevent the observation of other events.</li>
<li>Kaplan-Meier can overestimate the probability of an event of interest when competing risks are treated as ordinary censoring.</li>
<li>Cause-specific Cox models remain useful for modelling cause-specific hazards, but do not directly estimate cumulative incidence.</li>
<li>The cause-specific hazard function measures the instantaneous risk of a specific event type.</li>
<li>The cause-specific cumulative incidence function gives the probability of experiencing a specific event type over time.</li>
<li>The Aalen-Johansen estimator is the non-parametric method for estimating cumulative incidence in competing risks scenarios.</li>
<li>The Fine-Gray model allows regression analysis for competing risks data by modelling the sub-distribution hazard.</li>
<li>Stratification can accommodate non-proportional hazards in both Cox and Fine-Gray models.</li>
</ul>
</div>
</div>
</section>
<section id="coming-next" class="level2">
<h2 class="anchored" data-anchor-id="coming-next">Coming next</h2>
<p>The competing risks models shown in this post are a special case of <em>multi-state models</em>. In the next post, I’ll provide some of the theory of multi-state models and their applications in epidemiology, including estimating transition intensities and future states.</p>
</section>
<section id="references" class="level2">
<h2 class="anchored" data-anchor-id="references">References</h2>
<ul>
<li>Aalen OO, Johansen S. <a href="http://www.jstor.org/stable/4615704">An Empirical Transition Matrix for Non-Homogeneous Markov Chains Based on Censored Observations</a>. <em>Scand Stat Theory Appl</em>. 1978;5(3):141-50.</li>
<li>Borgan, Ø. <a href="https://onlinelibrary.wiley.com/doi/abs/10.1002/9781118445112.stat06045">Nelson-Aalen Estimator</a>. <em>Wiley StatsRef: Statistics Reference Online</em>. 2014.</li>
<li>Collett, D. <a href="https://www.taylorfrancis.com/books/mono/10.1201/9781003282525/modelling-survival-data-medical-research-david-collett">Modelling Survival Data in Medical Research</a>. <em>Chapman &amp; Hall/CRC Texts in Statistical Science</em>. 2023.</li>
<li>Fine JP, Gray RJ. <a href="https://www.tandfonline.com/doi/abs/10.1080/01621459.1999.10474144">A proportional hazards model for the subdistribution of a competing risk</a>. <em>J Am Stat Assoc</em>. 1999;94(446):496-509.</li>
<li>Hosmer DW, Lemeshow S. <a href="https://onlinelibrary.wiley.com/doi/book/10.1002/9780470258019">Applied survival analysis: Regression modeling of time to event data</a>. <em>Wiley</em>. 1999.</li>
</ul>
<div class="post-navigation">
<p><a href="../../blog/classical-survival-methods/index.html">← Previous post</a></p>
<p><a href="../../index.html#blog">Back to all posts</a></p>
<p><a href="../../blog/multi-state-models/index.html">Next post →</a></p>
</div>


</section>

<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-reuse"><h2 class="anchored quarto-appendix-heading">Reuse</h2><div class="quarto-appendix-contents"><div><a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a></div></div></section><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre class="sourceCode code-with-copy quarto-appendix-bibtex"><code class="sourceCode bibtex">@online{kirwan2025,
  author = {Kirwan, Peter},
  title = {Part {IV:} {Competing} Risks Survival Methods},
  date = {2025-08-19},
  url = {https://www.pkirwan.com/blog/competing-risks-methods/},
  langid = {en}
}
</code></pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-kirwan2025" class="csl-entry quarto-appendix-citeas">
Kirwan, Peter. 2025. <span>“Part IV: Competing Risks Survival
Methods.”</span> August 19. <a href="https://www.pkirwan.com/blog/competing-risks-methods/">https://www.pkirwan.com/blog/competing-risks-methods/</a>.
</div></div></section></div> ]]></description>
  <category>Competing risks</category>
  <category>Stratification</category>
  <guid>https://www.pkirwan.com/blog/competing-risks-methods/</guid>
  <pubDate>Tue, 19 Aug 2025 00:00:00 GMT</pubDate>
  <media:content url="https://www.pkirwan.com/blog/competing-risks-methods/competing-risks-banner.png" medium="image" type="image/png" height="72" width="144"/>
</item>
<item>
  <title>Part III: Classical survival methods</title>
  <dc:creator>Peter Kirwan</dc:creator>
  <link>https://www.pkirwan.com/blog/classical-survival-methods/</link>
  <description><![CDATA[ 






<p>This is part three of a series on statistical methods for infectious disease epidemiology, with a focus on time-to-event, or “survival”, data.</p>
<section id="statistical-inference" class="level2">
<h2 class="anchored" data-anchor-id="statistical-inference">Statistical inference</h2>
<p>Statistical inference is the process of using data to infer the properties of an underlying probability distribution. In the context of survival analysis, we want to estimate the distribution of time-to-event data, which is often incomplete due to censoring or truncation. This is a key challenge in survival analysis, as we need to account for the possibility that we do not observe the event of interest for all individuals in our study. For more details about censored and truncated data see the <a href="../../blog/survival-analysis/index.html">previous post</a> in this series.</p>
</section>
<section id="likelihood-estimation" class="level2">
<h2 class="anchored" data-anchor-id="likelihood-estimation">Likelihood estimation</h2>
<p>The likelihood function, often termed <img src="https://latex.codecogs.com/png.latex?L">, is used to connect statistical models to observed data in both the frequentist and Bayesian frameworks. The likelihood is the probability of observing the data, <img src="https://latex.codecogs.com/png.latex?D">, given the parameters, <img src="https://latex.codecogs.com/png.latex?%5Ctheta">, of the model and formally expressed as:</p>
<p><img src="https://latex.codecogs.com/png.latex?L(%5Ctheta%20%5Cmid%20D)%20=%20f(D%20%5Cmid%20%5Ctheta)%20=%20%5Cprod_i%20f(X_i%20%5Cmid%20%5Ctheta)"></p>
<p>where <img src="https://latex.codecogs.com/png.latex?f"> is the probability density function, and <img src="https://latex.codecogs.com/png.latex?X_i"> are assumed to be i.i.d observations in the data.</p>
<section id="frequentist-bayesian" class="level3">
<h3 class="anchored" data-anchor-id="frequentist-bayesian">Frequentist vs Bayesian</h3>
<p>In the ‘frequentist’ framework the parameters of a statistical model are considered to have a fixed ‘true’ unknown value to be estimated, and the data are realisations of random variables. The parameters of the model are estimated by maximising the likelihood to obtain the maximum likelihood estimate (MLE), denoted <img src="https://latex.codecogs.com/png.latex?%5Chat%7B%5Ctheta%7D">.</p>
<p>Bayesian methods are an alternative to maximum likelihood estimation, used to estimate the probability distribution of the parameters of the model given the data, known as the ‘posterior distribution’. In the Bayesian framework, all quantities (both observable quantities and parameters) are considered as random variables, with observed data being realisations of these random variables. The posterior distribution, <img src="https://latex.codecogs.com/png.latex?f(%5Ctheta%20%5Cmid%20D)">, is related to the likelihood function, <img src="https://latex.codecogs.com/png.latex?f(D%20%5Cmid%20%5Ctheta)">, via Bayes formula:</p>
<p><img src="https://latex.codecogs.com/png.latex?%20f(%5Ctheta%20%5Cmid%20D)%20=%20%5Cfrac%7Bf(D%20%5Cmid%20%5Ctheta)f(%5Ctheta)%7D%7Bf(D)%7D"></p>
</section>
<section id="censored-truncated" class="level3">
<h3 class="anchored" data-anchor-id="censored-truncated">Censored and truncated data</h3>
<p>Constructing likelihoods for censored or truncated data requires careful consideration of the information provided by each observation. The <a href="../../blog/survival-analysis/index.html">previous post</a> in this series provided a definition of censoring and truncation, and the right and left censoring and truncation times.</p>
<p>The likelihood components provided by censored observations, assuming that censoring is independent of the event process, are:</p>
<ul>
<li>for exactly observed data: information on the probability of the event occurring at this time, i.e.&nbsp;<img src="https://latex.codecogs.com/png.latex?f(X)"></li>
<li>for right-censored observations: information on the survivor function up to a certain time, i.e.&nbsp;<img src="https://latex.codecogs.com/png.latex?S(C_r)"></li>
<li>for left-censored observations: information on the cumulative incidence up to a certain time, i.e.&nbsp;<img src="https://latex.codecogs.com/png.latex?F(C_l)"></li>
<li>for interval-censored observations: information on the probability that the event is within this interval, i.e.&nbsp;<img src="https://latex.codecogs.com/png.latex?S(L)%20-%20S(R)">.</li>
</ul>
<p>As data may be observed with different levels of censoring or truncation, the likelihood function is constructed from the joint product of each component for each observation <img src="https://latex.codecogs.com/png.latex?i">:</p>
<p><img src="https://latex.codecogs.com/png.latex?L%20%5Cpropto%20%5Cprod_%7Bi%7D%20f(X_i)%20%5Cprod_%7Bi%7D%20S(C_%7Br,i%7D)%20%5Cprod_%7Bi%7D%20F(C_%7Bl,i%7D)%20%5Cprod_i%20(S(L_i)%20-%20S(R_i))"></p>
<p>The equivalent likelihood components for truncated data provide information on conditional probabilities of events, given that the individual was observed:</p>
<ul>
<li>for left-truncated observations, where observation is conditional on the event time being at least the left-truncation time <img src="https://latex.codecogs.com/png.latex?Y_l">: <img src="https://latex.codecogs.com/png.latex?f(X)/S(Y_l)"></li>
<li>for right-truncated observations, where observation is conditional on the event of interest having occurred by the truncation time <img src="https://latex.codecogs.com/png.latex?Y_r">: <img src="https://latex.codecogs.com/png.latex?f(X)/F(Y_r)"></li>
<li>for interval-truncated observations, where observation is conditional on the event occurring within the truncation interval <img src="https://latex.codecogs.com/png.latex?%5BY_l,%20Y_r%5D">: <img src="https://latex.codecogs.com/png.latex?f(X)/%5C%7BF(Y_r)%20-%20F(Y_l)%5C%7D">.</li>
</ul>
</section>
</section>
<section id="parametric-non-parametric" class="level2">
<h2 class="anchored" data-anchor-id="parametric-non-parametric">Parametric and non-parametric models</h2>
<p>The statistical models used for estimating model parameters may be parametric or non-parametric. In general, parametric models rely on assumptions about the distribution of the underlying survival times (e.g.&nbsp;Weibull, Gamma, etc.), so careful selection of this distribution is needed for valid inference.</p>
<p>In contrast, non-parametric models require fewer assumptions about the survival distribution, so can be applied when the functional form of the distribution is not known, but may require more data and not allow for extrapolation beyond the time period of the observed data. Comparisons to non-parametric estimates can be made to assess the fit of a parametric model.</p>
</section>
<section id="kaplan-meier" class="level2">
<h2 class="anchored" data-anchor-id="kaplan-meier">The Kaplan-Meier estimator</h2>
<p>The Kaplan-Meier estimator is a widely-used, non-parametric method to estimate the survivor function, <img src="https://latex.codecogs.com/png.latex?S(t)">, from censored data, and defined as:</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Chat%7BS%7D(t)%20=%20%5Cprod_%7Bt_k%20%5Cleq%20t%7D%5Cleft(%5Cfrac%7Bn(t_k)%20-%20d(t_k)%7D%7Bn(t_k)%7D%5Cright)"></p>
<p>where <img src="https://latex.codecogs.com/png.latex?d(t_k)"> is the number of events, and <img src="https://latex.codecogs.com/png.latex?n(t_k)"> is the number of individuals at risk just before time <img src="https://latex.codecogs.com/png.latex?t_k">, for the observed event times <img src="https://latex.codecogs.com/png.latex?t_k%20%5Cleq%20t">.</p>
<p>The Kaplan-Meier estimator is a step function, with jumps at each observed event time. At each event time the estimate is multiplied by the proportion of individuals at risk who do not experience the event, so the size of each jump depends on both the number of events and the number still at risk. The Kaplan-Meier estimator is often plotted as a survival curve, with time on the x-axis and the estimated survival probability on the y-axis, as shown in Figure&nbsp;1 below.</p>
<section id="r-example-km" class="level3">
<h3 class="anchored" data-anchor-id="r-example-km">R example</h3>
<p>For a short example of the product-limit construction we can use the <code>survival</code> package in R to compute a Kaplan-Meier estimate from a small dataset of 10 observations, with some censored and some observed event times:</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" data-lst-cap="Computing a Kaplan-Meier estimate in R." style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb1-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(survival)</span>
<span id="cb1-2"></span>
<span id="cb1-3">km_data <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">data.frame</span>(</span>
<span id="cb1-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">time   =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>),</span>
<span id="cb1-5">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">status =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>,  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,  <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span>
<span id="cb1-6">)</span>
<span id="cb1-7"></span>
<span id="cb1-8">km_fit <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">survfit</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Surv</span>(time, status) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> km_data)</span>
<span id="cb1-9"></span>
<span id="cb1-10"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">data.frame</span>(</span>
<span id="cb1-11">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">time     =</span> km_fit<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>time,</span>
<span id="cb1-12">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n_risk   =</span> km_fit<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>n.risk,</span>
<span id="cb1-13">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n_event  =</span> km_fit<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>n.event,</span>
<span id="cb1-14">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n_censor =</span> km_fit<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>n.censor,</span>
<span id="cb1-15">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">survival =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(km_fit<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>surv, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span>
<span id="cb1-16">)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>  time n_risk n_event n_censor survival
1    2     10       1        0     0.90
2    3      9       1        0     0.80
3    4      8       1        1     0.70
4    5      6       1        0     0.58
5    6      5       0        1     0.58
6    7      4       1        0     0.44
7    8      3       0        1     0.44
8   10      2       1        1     0.22</code></pre>
</div>
</div>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb3-1">km_df <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">data.frame</span>(</span>
<span id="cb3-2">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">time   =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, km_fit<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>time),</span>
<span id="cb3-3">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">surv   =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, km_fit<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>surv),</span>
<span id="cb3-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">lower  =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, km_fit<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>lower),</span>
<span id="cb3-5">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">upper  =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, km_fit<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>upper),</span>
<span id="cb3-6">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">censor =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>L, km_fit<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>n.censor)</span>
<span id="cb3-7">)</span>
<span id="cb3-8"></span>
<span id="cb3-9"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(km_df, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> time)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb3-10">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_step</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> lower), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">colour =</span> blog_cols[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"red"</span>]], <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">linetype =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"dotted"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb3-11">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_step</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> upper), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">colour =</span> blog_cols[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"red"</span>]], <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">linetype =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"dotted"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb3-12">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_step</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> surv), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">colour =</span> blog_cols[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"red"</span>]], <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">linewidth =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.1</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb3-13">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_point</span>(</span>
<span id="cb3-14">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">subset</span>(km_df, censor <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>),</span>
<span id="cb3-15">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> surv), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">shape =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">size =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">stroke =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span>
<span id="cb3-16">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb3-17">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_y_continuous</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">limits =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">name =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Estimated survival"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb3-18">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_x_continuous</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">name =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Follow-up time (days)"</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<div id="fig-km" class="quarto-float quarto-figure quarto-figure-center anchored" alt="Step plot of estimated survival, falling from 1 at time 0 to about 0.22 at day 10, with crosses where observations are censored and dotted lines showing wide 95% confidence limits.">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-km-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://www.pkirwan.com/blog/classical-survival-methods/index_files/figure-html/fig-km-1.png" class="img-fluid figure-img" alt="Step plot of estimated survival, falling from 1 at time 0 to about 0.22 at day 10, with crosses where observations are censored and dotted lines showing wide 95% confidence limits." width="672">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-km-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;1: Kaplan-Meier survival curve for the example data. Crosses mark censored observations and dotted lines show pointwise 95% confidence limits.
</figcaption>
</figure>
</div>
</div>
</div>
<p>The figure shows the Kaplan-Meier survival curve, with steps at each observed event time and crosses indicating censored observations (including those which coincide with an event time, at days 4 and 10). Survival only steps down at observed event times (rows where <code>n_event &gt; 0</code>), while censored observations reduce the risk set without causing a jump. With only 10 observations the confidence limits are wide.</p>
</section>
</section>
<section id="cox-proportional-hazards" class="level2">
<h2 class="anchored" data-anchor-id="cox-proportional-hazards">The Cox proportional hazards model</h2>
<p>The Cox proportional hazards model assumes that the hazards of death for any two individuals are <em>proportional</em> over time, expressed by writing the hazard function conditional on a given set of <img src="https://latex.codecogs.com/png.latex?M"> constant covariates <img src="https://latex.codecogs.com/png.latex?%5Cboldsymbol%7Bz%7D%20=%20%5C%7Bz_%7B1%7D%5Cldots,%20z_%7BM%7D%5C%7D"> as:</p>
<p><img src="https://latex.codecogs.com/png.latex?h(t%20%5Cmid%20%5Cboldsymbol%7Bz%7D)%20=%20h%5E%7B(0)%7D(t)%5Cexp%5Cleft(%5Csum_%7Bm=1%7D%5E%7BM%7D%5Cbeta_%7Bm%7Dz_%7Bm%7D%5Cright)%20%5Cequiv%20h%5E%7B(0)%7D(t)%5Cexp(%5Cboldsymbol%7B%5Cbeta%7D%5E%5Cmathsf%7BT%7D%5Cboldsymbol%7Bz%7D)"></p>
<p>where <img src="https://latex.codecogs.com/png.latex?h%5E%7B(0)%7D(t)"> is the baseline hazard function, and <img src="https://latex.codecogs.com/png.latex?%5Cbeta_%7Bm%7D"> are the regression coefficients. Notably, the ‘hazard ratio’ for the <img src="https://latex.codecogs.com/png.latex?m">th covariate is a constant:</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cfrac%7Bh(t%20%5Cmid%20z_m%20=%201)%7D%7Bh(t%20%5Cmid%20z_m%20=%200)%7D%20=%20%5Cfrac%7Bh%5E%7B(0)%7D(t)%5Cexp(%5Cbeta_m%201)%7D%7Bh%5E%7B(0)%7D(t)%5Cexp(%5Cbeta_m%200)%7D%20=%20%5Cexp(%5Cbeta_%7Bm%7D)"></p>
<p>The regression coefficients <img src="https://latex.codecogs.com/png.latex?%5Cbeta_%7Bm%7D"> are estimated by maximising the partial likelihood <img src="https://latex.codecogs.com/png.latex?L(%5Cboldsymbol%7B%5Cbeta%7D)"> (shown here assuming there are no tied failure times):</p>
<p><img src="https://latex.codecogs.com/png.latex?L(%5Cboldsymbol%7B%5Cbeta%7D)%20=%20%5Cprod_%7Bi%20%5Cin%20%5Cmathcal%7BE%7D%7D%5Cfrac%7B%5Cexp(%5Cboldsymbol%7B%5Cbeta%7D%5E%5Cmathsf%7BT%7D%5Cboldsymbol%7Bz%7D_%7Bd_i%7D)%7D%7B%5Csum_%7Bj%20%5Cin%20R_i%7D%5Cexp(%5Cboldsymbol%7B%5Cbeta%7D%5E%5Cmathsf%7BT%7D%5Cboldsymbol%7Bz%7D_j)%7D"></p>
<p>where <img src="https://latex.codecogs.com/png.latex?%5Cmathcal%7BE%7D%20=%20%5C%7BT_1,%20T_2,%20%5Cldots,%20T_n%5C%7D"> are the set of distinct failure times, <img src="https://latex.codecogs.com/png.latex?R_i"> is the set of all individuals who are at risk of failure immediately before time <img src="https://latex.codecogs.com/png.latex?T_i">, <img src="https://latex.codecogs.com/png.latex?%5Cboldsymbol%7Bz%7D_%7Bd_i%7D"> is the covariate vector for an individual who failed at time <img src="https://latex.codecogs.com/png.latex?T_i">, and <img src="https://latex.codecogs.com/png.latex?%5Cboldsymbol%7Bz%7D_j"> is the covariate vector for the <img src="https://latex.codecogs.com/png.latex?j">th individual at risk at time <img src="https://latex.codecogs.com/png.latex?T_i">. The model can be extended to time-varying covariates <img src="https://latex.codecogs.com/png.latex?%5Cboldsymbol%7Bz%7D(t)">, in which case the hazard ratio is no longer constant over time.</p>
<p>In practice, the proportional hazards assumption should be assessed before interpreting hazard ratios, for example using Schoenfeld residuals or by allowing covariate effects to vary over time.</p>
<section id="r-example-cox" class="level3">
<h3 class="anchored" data-anchor-id="r-example-cox">R example</h3>
<p>To illustrate fitting a Cox proportional hazards model, we can use the <code>survival</code> package in R to fit a model to the <code>lung</code> dataset, which contains survival data for patients with advanced lung cancer. We’ll model the hazard of death as a function of age and sex, and check the proportional hazards assumption using Schoenfeld residuals.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb4" data-lst-cap="Fitting and checking a Cox proportional hazards model in R." style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb4-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(survival)</span>
<span id="cb4-2"></span>
<span id="cb4-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># lung: time to death (days) for advanced lung cancer patients</span></span>
<span id="cb4-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># status: 1 = censored, 2 = dead; sex: 1 = male, 2 = female</span></span>
<span id="cb4-5">cox_fit <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">coxph</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Surv</span>(time, status <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> age <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> sex, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> lung)</span>
<span id="cb4-6"></span>
<span id="cb4-7"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summary</span>(cox_fit)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>coefficients[, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"coef"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"exp(coef)"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Pr(&gt;|z|)"</span>)], <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>      coef exp(coef) Pr(&gt;|z|)
age  0.017     1.017    0.065
sex -0.513     0.599    0.002</code></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb6" data-lst-cap="Fitting and checking a Cox proportional hazards model in R." style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb6-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">cox.zph</span>(cox_fit)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>table[, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"p"</span>], <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>   age    sex GLOBAL 
 0.647  0.106  0.250 </code></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb8" data-lst-cap="Fitting and checking a Cox proportional hazards model in R." style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb8-1">ci <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summary</span>(cox_fit)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>conf.int</span>
<span id="cb8-2">coef_df <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">data.frame</span>(</span>
<span id="cb8-3">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">term =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Age (per year)"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Sex (female vs male)"</span>),</span>
<span id="cb8-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">hr   =</span> ci[, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"exp(coef)"</span>],</span>
<span id="cb8-5">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">lo   =</span> ci[, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"lower .95"</span>],</span>
<span id="cb8-6">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">hi   =</span> ci[, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"upper .95"</span>]</span>
<span id="cb8-7">)</span>
<span id="cb8-8"></span>
<span id="cb8-9"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(coef_df, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> hr, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> term)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb8-10">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_vline</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">xintercept =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">linetype =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"dashed"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">colour =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gray50"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb8-11">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_errorbar</span>(</span>
<span id="cb8-12">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">xmin =</span> lo, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">xmax =</span> hi),</span>
<span id="cb8-13">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">orientation =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"y"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">width =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">colour =</span> blog_cols[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"dark"</span>]]</span>
<span id="cb8-14">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb8-15">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_point</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">size =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">colour =</span> blog_cols[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"red"</span>]]) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb8-16">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_x_log10</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">name =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Hazard ratio (log scale)"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb8-17">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_y_discrete</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">name =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">NULL</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.pkirwan.com/blog/classical-survival-methods/index_files/figure-html/lst-cox-model-1.png" class="img-fluid figure-img" alt="Forest plot of hazard ratios on a log scale. The hazard ratio for age per year is slightly above 1 with a confidence interval that includes 1. The hazard ratio for female versus male sex is about 0.6, with a confidence interval entirely below 1." width="672"></p>
</figure>
</div>
</div>
</div>
<p>Older age increases the hazard of death (<code>exp(coef) &gt; 1</code>), although there is only weak evidence of an effect (p = 0.06). Female sex is protective (<code>exp(coef) &lt; 1</code>), and there is strong evidence of this effect (p = 0.002). The Schoenfeld test p-values give a quick check of the proportional hazards assumption: here, there is no strong evidence against it (all p &gt; 0.05), but a non-significant test does not prove that the assumption holds, so the residuals should also be inspected graphically with <code>plot(cox.zph(cox_fit))</code>.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
<span class="screen-reader-only">Note</span>Key takeaways
</div>
</div>
<div class="callout-body-container callout-body">
<ul>
<li>Statistical inference allows us to estimate survival distributions despite incomplete data from censoring or truncation.</li>
<li>Likelihood functions connect our statistical models to observed data, with special adaptations for censored and truncated observations.</li>
<li>Parametric models assume a specific distribution for survival times, while non-parametric approaches make fewer assumptions.</li>
<li>The Kaplan-Meier estimator is a non-parametric method to estimate the survivor function from censored data.</li>
<li>The Cox proportional hazards model relates survival times to explanatory variables through a semi-parametric approach.</li>
<li>The proportional hazards assumption means that the ratio of hazards between different groups remains constant over time.</li>
</ul>
</div>
</div>
</section>
</section>
<section id="coming-next" class="level2">
<h2 class="anchored" data-anchor-id="coming-next">Coming next</h2>
<p>In the next post, I’ll explain how to handle scenarios where multiple possible events can occur, and the challenges this presents for traditional survival methods. I’ll introduce two methods for competing risks data, analogous to the Kaplan-Meier and Cox models described above:</p>
<ul>
<li>The Aalen-Johansen estimator - a non-parametric method for estimating the cumulative incidence function.</li>
<li>The Fine-Gray model - a regression model for estimating the effect of covariates on the subdistribution hazard.</li>
</ul>
</section>
<section id="references" class="level2">
<h2 class="anchored" data-anchor-id="references">References</h2>
<ul>
<li>Austin PC. <a href="http://dx.doi.org/10.1111/insr.12214">A Tutorial on Multilevel Survival Analysis: Methods, Models and Applications</a>. <em>Int Stat Rev</em>. 2017;85(2):185-203.</li>
<li>Collett D. <a href="https://www.taylorfrancis.com/books/mono/10.1201/9781003282525/modelling-survival-data-medical-research-david-collett">Modelling Survival Data in Medical Research</a>. <em>Chapman &amp; Hall/CRC Texts in Statistical Science</em>. 2023.</li>
<li>Klein JP, Moeschberger ML. <a href="https://play.google.com/store/books/details?id=KSq0e-6VFJ0C">Survival Analysis: Techniques for Censored and Truncated Data</a>. <em>Springer Science &amp; Business Media</em>; 2005.</li>
<li>Wasserman LA. <a href="https://books.google.com/books?hl=en&amp;lr=&amp;id=th3fbFI1DaMC&amp;oi=fnd&amp;pg=PA1&amp;dq=All+Statistics+Concise+Course+Statistical+Inference+Wasserman&amp;ots=eRiUBZMis9&amp;sig=o9uqf2nz1ytzCEOVbRS2oXprG8w">All of statistics</a>. <em>Springer</em>. 2004.</li>
</ul>
<div class="post-navigation">
<p><a href="../../blog/survival-analysis/index.html">← Previous post</a></p>
<p><a href="../../index.html#blog">Back to all posts</a></p>
<p><a href="../../blog/competing-risks-methods/index.html">Next post →</a></p>
</div>


</section>

<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-reuse"><h2 class="anchored quarto-appendix-heading">Reuse</h2><div class="quarto-appendix-contents"><div><a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a></div></div></section><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre class="sourceCode code-with-copy quarto-appendix-bibtex"><code class="sourceCode bibtex">@online{kirwan2025,
  author = {Kirwan, Peter},
  title = {Part {III:} {Classical} Survival Methods},
  date = {2025-07-22},
  url = {https://www.pkirwan.com/blog/classical-survival-methods/},
  langid = {en}
}
</code></pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-kirwan2025" class="csl-entry quarto-appendix-citeas">
Kirwan, Peter. 2025. <span>“Part III: Classical Survival
Methods.”</span> July 22. <a href="https://www.pkirwan.com/blog/classical-survival-methods/">https://www.pkirwan.com/blog/classical-survival-methods/</a>.
</div></div></section></div> ]]></description>
  <category>Likelihood</category>
  <category>Survival models</category>
  <guid>https://www.pkirwan.com/blog/classical-survival-methods/</guid>
  <pubDate>Tue, 22 Jul 2025 00:00:00 GMT</pubDate>
  <media:content url="https://www.pkirwan.com/blog/classical-survival-methods/survival-methods-banner.png" medium="image" type="image/png" height="69" width="144"/>
</item>
<item>
  <title>Part II: Survival analysis</title>
  <dc:creator>Peter Kirwan</dc:creator>
  <link>https://www.pkirwan.com/blog/survival-analysis/</link>
  <description><![CDATA[ 






<p>This is part two of a series on statistical methods for infectious disease epidemiology, with a focus on time-to-event, or “survival”, data.</p>
<section id="what-is-survival-analysis" class="level2">
<h2 class="anchored" data-anchor-id="what-is-survival-analysis">What is survival analysis?</h2>
<p>Survival analysis involves studying “time-to-event” data, also termed “survival data” - a powerful statistical framework that helps us answer questions about <em>when</em> events occur. It applies to any scenario where we’re interested in the time from a given origin to the occurrence of an event (the endpoint).</p>
<p>In infectious disease research, survival data are commonly used to describe clinical origins and endpoints, for example:</p>
<ul>
<li>Time from study recruitment to infection</li>
<li>Duration from hospitalisation to discharge</li>
<li>Period from infection until recovery or death</li>
</ul>
<p>These data may be combined with information on patient characteristics (age, gender, socioeconomic status) and clinical variables (vaccination status, treatments). Survival analysis techniques help us to understand how these factors influence outcomes.</p>
</section>
<section id="incomplete-information" class="level2">
<h2 class="anchored" data-anchor-id="incomplete-information">Incomplete information</h2>
<p>One of the most distinctive aspects of survival analysis is how it handles incomplete information. In real-world studies, we often don’t observe the complete “story” for each participant. This incompleteness comes in several forms:</p>
<section id="censoring" class="level3">
<h3 class="anchored" data-anchor-id="censoring">Censoring</h3>
<p>Censoring occurs when information about an individual is only known within certain intervals or “censoring times”.</p>
<section id="right-censoring" class="level4">
<h4 class="anchored" data-anchor-id="right-censoring">Right-censoring</h4>
<p>The most common type of censoring occurs when our study ends before we observe the event of interest. For example, if we’re studying time to COVID-19 infection, and a participant remains uninfected when our study concludes, they’re “right-censored” - we know they remained infection-free for at least the duration of the study, but we don’t know what happens afterward.</p>
<p>More formally, we lack information to the right (or future) of the right-censoring time, <img src="https://latex.codecogs.com/png.latex?C_r">. In this scenario we say an individual is right-censored at time <img src="https://latex.codecogs.com/png.latex?C_r%20%3C%20X">, where <img src="https://latex.codecogs.com/png.latex?X"> is the time that the event of interest takes place.</p>
</section>
<section id="left-censoring" class="level4">
<h4 class="anchored" data-anchor-id="left-censoring">Left-censoring</h4>
<p>If, on the other hand, the event of interest occurs at an unknown time, <img src="https://latex.codecogs.com/png.latex?X">, before we started observing the participant at time <img src="https://latex.codecogs.com/png.latex?C_l"> this is known as “left-censoring”. For instance, if we’re studying HIV infection, and a participant tests positive at their first visit, we know they acquired HIV at some point before joining the study, but we don’t know exactly when. In this scenario we say the individual is left-censored at time <img src="https://latex.codecogs.com/png.latex?C_l%20%3E%20X">.</p>
</section>
<section id="administrative-censoring" class="level4">
<h4 class="anchored" data-anchor-id="administrative-censoring">Administrative censoring</h4>
<p>Sometimes we impose censoring on our dataset, limiting the time-to-event data for each individual to a pre-specified cut-off, with any events beyond this period not considered, e.g.&nbsp;mortality within 30 days of hospital admission. This is known as administrative censoring.</p>
<div id="fig-censoring" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-censoring-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell">
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.pkirwan.com/blog/survival-analysis/index_files/figure-html/unnamed-chunk-2-1.png" class="img-fluid figure-img" alt="Four horizontal lines, one per patient. The first has an observed origin and outcome. The second is right-censored and ends at the right-censoring time without an outcome. The third is left-censored, with no observed origin before the left-censoring time. The fourth is administratively censored and ends at a 30 day cut-off." width="672"></p>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-censoring-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;1: Examples of right, left, and administrative censoring for patients in time-to-event data. <img src="https://latex.codecogs.com/png.latex?C_l">: left-censoring time, <img src="https://latex.codecogs.com/png.latex?C_r">: right-censoring time, <img src="https://latex.codecogs.com/png.latex?%5Cbullet">: reported origin, outcome, or intermediate event. Lines without a final <img src="https://latex.codecogs.com/png.latex?%5Cbullet"> end at the time of censoring.
</figcaption>
</figure>
</div>
</section>
<section id="interval-censoring" class="level4">
<h4 class="anchored" data-anchor-id="interval-censoring">Interval censoring</h4>
<p>Often, we only know that an event happened between two observation points, i.e.&nbsp;within a censoring interval <img src="https://latex.codecogs.com/png.latex?(L,%20R%5D,%5C%20L%20%3C%20X%20%5Cleq%20R">. An example is the infection time for an individual which is typically not directly observed, but we can assume it occurs in-between a negative and positive test. Interval censoring is a feature of “intermittently-observed” data, where individuals are tested for the presence of infection at several time-points. Such interval-censored data can still be used to detect changes in an individual’s infection status when testing is sufficiently frequent, as shown in Figure&nbsp;2. Here the transitions between states take place between observation times, so we only know that each change occurred within the interval between two visits.</p>
<div id="fig-interval-censoring" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-interval-censoring-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell">
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.pkirwan.com/blog/survival-analysis/index_files/figure-html/unnamed-chunk-3-1.png" class="img-fluid figure-img" alt="Step plot of an underlying process which moves from state 1 to state 2 at week 3 and back to state 1 at week 7. Dashed vertical lines mark observation times every two weeks from week 2 to week 12, so each change falls between two observations." width="672"></p>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-interval-censoring-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;2: Example of interval censoring with intermittently-observed data for an underlying process.
</figcaption>
</figure>
</div>
</section>
</section>
<section id="truncation" class="level3">
<h3 class="anchored" data-anchor-id="truncation">Truncation</h3>
<p>While censoring gives us partial information, truncation occurs when information about an individual is completely unobserved, and unavailable at the time of data collection or analysis. This is different from censoring because censored individuals are at least partially observed, while truncated individuals never enter our dataset. As with censoring, left-, right-, and interval-truncation are possible.</p>
<ul>
<li><strong>Left truncation</strong>: occurs when only event-times which take place after the left-truncation time, <img src="https://latex.codecogs.com/png.latex?Y_l">, are available. For example, if individuals whose infection occurs prior to the study, <img src="https://latex.codecogs.com/png.latex?X%20%3C%20Y_l">, are not included in our dataset.</li>
<li><strong>Right-truncation</strong>: occurs when only event-times which take place before the right-truncation time, <img src="https://latex.codecogs.com/png.latex?Y_r">, are available. For example, when we have no knowledge of individuals who are at risk but whose event of interest takes place after the study endpoint, <img src="https://latex.codecogs.com/png.latex?X%20%3E%20Y_r">.</li>
<li><strong>Interval-truncation</strong>: occurs when only event-times which take place within a specific truncation interval <img src="https://latex.codecogs.com/png.latex?%5BY_l,%20Y_r%5D"> are available for observation. The key difference from left- and right-truncation is that in interval-truncation, both the left and right boundaries of the observation window play a role in determining which event-times are observed.</li>
</ul>
<div id="fig-truncation" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-truncation-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell">
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.pkirwan.com/blog/survival-analysis/index_files/figure-html/unnamed-chunk-4-1.png" class="img-fluid figure-img" alt="Three horizontal lines between two dashed vertical lines marking the left and right truncation times. The first line, with an event between the two times, is observed. The second, with an event after the right truncation time, and the third, with an event before the left truncation time, are drawn in grey and are not in the dataset." width="672"></p>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-truncation-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;3: Examples of left and right-truncation for patients in time-to-event data, assuming only information within the truncation interval (<img src="https://latex.codecogs.com/png.latex?Y_l">, <img src="https://latex.codecogs.com/png.latex?Y_r">) is observed. Truncated individuals (grey, dashed) never enter the dataset. The first patient has an event time inside the interval and is therefore observed, as under interval-truncation. <img src="https://latex.codecogs.com/png.latex?Y_l">: left-truncation time, <img src="https://latex.codecogs.com/png.latex?Y_r">: right-truncation time, <img src="https://latex.codecogs.com/png.latex?%5Cbullet">: outcome time.
</figcaption>
</figure>
</div>
</section>
</section>
<section id="key-concepts" class="level2">
<h2 class="anchored" data-anchor-id="key-concepts">When standard statistics aren’t enough</h2>
<p>Why can’t we just use regular statistical methods like t-tests or linear regression for time-to-event data? The key challenge is that censoring and truncation create a form of missing data that’s not random. If we removed all censored observations or treated censoring times as event times, we’d introduce severe bias.</p>
<p>Survival methods typically also assume that censoring is <em>independent</em> (or “non-informative”): an individual who is censored at time <img src="https://latex.codecogs.com/png.latex?t"> should be representative of the individuals who remain under observation at <img src="https://latex.codecogs.com/png.latex?t">. For example, if participants withdraw from a study because their health is deteriorating then censoring is informative, and the methods described in this series may give biased results unless this is accounted for.</p>
<p>Survival analysis methods are specifically designed for valid statistical estimation of incomplete data while avoiding these biases. We’ll start off by defining several fundamental functions for survival analysis:</p>
<section id="cumulative-incidence" class="level3">
<h3 class="anchored" data-anchor-id="cumulative-incidence">The cumulative incidence function</h3>
<p>Let <img src="https://latex.codecogs.com/png.latex?T"> be the random variable representing the survival time, <img src="https://latex.codecogs.com/png.latex?T%20=%20t%20%3E%200">, for an individual, with survival times assumed to be independent and identically distributed (i.i.d) across individuals, and assume this random variable has a probability distribution with probability density function <img src="https://latex.codecogs.com/png.latex?f(t)">.</p>
<p>The distribution function of <img src="https://latex.codecogs.com/png.latex?T">, also known as the cumulative incidence function, is the probability of “failure” before time <img src="https://latex.codecogs.com/png.latex?t">, defined as:</p>
<p><img src="https://latex.codecogs.com/png.latex?F(t)%20=%20%5CPr(T%20%3C%20t)=%5Cint_0%5Et%20f(u)%20du"></p>
<p>When there are several possible events, as in <a href="../../blog/competing-risks-methods/index.html">part IV of this series</a>, this is extended to <em>cause-specific</em> cumulative incidence functions.</p>
</section>
<section id="survivor-function" class="level3">
<h3 class="anchored" data-anchor-id="survivor-function">The survivor function</h3>
<p>The survivor function <img src="https://latex.codecogs.com/png.latex?S(t)"> gives the probability of surviving (not experiencing the event) beyond time <img src="https://latex.codecogs.com/png.latex?t">. This is the cornerstone of survival analysis and is defined as:</p>
<p><img src="https://latex.codecogs.com/png.latex?S(t)%20=%20%5CPr(T%20%5Cgeq%20t)%20=%201%20-%20F(t)"></p>
<p>where <img src="https://latex.codecogs.com/png.latex?T"> is the random variable representing the time until the event occurs.</p>
<p>The survivor function starts at 1 (everyone is “alive” at time 0) and decreases toward 0 as time progresses. It has an intuitive interpretation: <img src="https://latex.codecogs.com/png.latex?S(6%20%5Ctext%7B%20months%7D)%20=%200.8"> means 80% of individuals remain event-free after 6 months.</p>
</section>
<section id="hazard-function" class="level3">
<h3 class="anchored" data-anchor-id="hazard-function">The hazard function</h3>
<p>The hazard function <img src="https://latex.codecogs.com/png.latex?h(t)"> represents the instantaneous rate of experiencing the event at time <img src="https://latex.codecogs.com/png.latex?t">, given survival up to that point. Think of it as the “risk” at each moment, conditional on having survived so far (although, as a rate, it is not a probability and can exceed 1):</p>
<p><img src="https://latex.codecogs.com/png.latex?h(t)%20=%20%5Clim_%7B%5Cdelta%20t%20%5Cdownarrow%200%7D%20%5Cfrac%7B%5CPr(t%20%5Cleq%20T%20%3C%20t+%5Cdelta%20t%20%7C%20T%20%5Cgeq%20t)%7D%7B%5Cdelta%20t%7D"></p>
<p>By conditional probability, <img src="https://latex.codecogs.com/png.latex?%5CPr(A%20%5Cmid%20B)%20=%20%5CPr(AB)/%5CPr(B)">, so the hazard function can also be expressed as:</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cbegin%7Baligned%7D%0Ah(t)%20&amp;=%20%5Clim_%7B%5Cdelta%20t%20%5Cdownarrow%200%7D%20%5Cleft%5C%7B%5Cfrac%7B%5CPr(t%20%5Cleq%20T%20%3C%20t%20+%20%5Cdelta%20t)%7D%7B%5Cdelta%20t%20%5CPr(T%20%5Cgeq%20t)%7D%5Cright%5C%7D%20%5C%5C%0A&amp;=%5Clim_%7B%5Cdelta%20t%20%5Cdownarrow%200%7D%20%5Cleft%5C%7B%5Cfrac%7BF(t%20+%20%5Cdelta%20t)%20-%20F(t)%7D%7B%5Cdelta%20t%20S(t)%7D%5Cright%5C%7D%20%5C%5C%0A&amp;=%5Clim_%7B%5Cdelta%20t%20%5Cdownarrow%200%7D%20%5Cleft%5C%7B%5Cfrac%7BF(t%20+%20%5Cdelta%20t)%20-%20F(t)%7D%7B%5Cdelta%20t%7D%5Cright%5C%7D%5Cfrac%7B1%7D%7BS(t)%7D%0A%5Cend%7Baligned%7D"></p>
<p>This limit is the definition of the derivative of <img src="https://latex.codecogs.com/png.latex?F(t)"> with respect to <img src="https://latex.codecogs.com/png.latex?t">, and therefore equal to <img src="https://latex.codecogs.com/png.latex?f(t)">:</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Clim_%7B%5Cdelta%20t%20%5Cdownarrow%200%7D%20%5Cleft%5C%7B%5Cfrac%7BF(t%20+%20%5Cdelta%20t)%20-%20F(t)%7D%7B%5Cdelta%20t%7D%5Cright%5C%7D%20=%20%5Cfrac%7Bd%7D%7Bdt%7DF(t)%20=%20f(t)"></p>
<p>Hence the hazard function is related to the survivor function through the relationship:</p>
<p><img src="https://latex.codecogs.com/png.latex?h(t)%20=%20%5Cfrac%7Bf(t)%7D%7BS(t)%7D"></p>
</section>
</section>
<section id="r-implementation" class="level2">
<h2 class="anchored" data-anchor-id="r-implementation">R implementation</h2>
<p>With all three functions defined, we can visualise how <img src="https://latex.codecogs.com/png.latex?F(t)">, <img src="https://latex.codecogs.com/png.latex?S(t)">, and <img src="https://latex.codecogs.com/png.latex?h(t)"> relate for a simple exponential model with a constant rate <img src="https://latex.codecogs.com/png.latex?%5Clambda%20=%200.15"> events per unit time:</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" data-lst-cap="Relating the cumulative incidence, survivor, and hazard functions in R." style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb1-1">rate      <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.15</span></span>
<span id="cb1-2">time_grid <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span>)</span>
<span id="cb1-3"></span>
<span id="cb1-4">data <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">data.frame</span>(</span>
<span id="cb1-5">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">time =</span> time_grid,</span>
<span id="cb1-6">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">F_t  =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pexp</span>(time_grid, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">rate =</span> rate), <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>),</span>
<span id="cb1-7">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">S_t  =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pexp</span>(time_grid, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">rate =</span> rate, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">lower.tail =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">FALSE</span>), <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>),</span>
<span id="cb1-8">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">h_t  =</span> rate</span>
<span id="cb1-9">)</span>
<span id="cb1-10"></span>
<span id="cb1-11"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">print</span>(data)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>  time  F_t  S_t  h_t
1    0 0.00 1.00 0.15
2    2 0.26 0.74 0.15
3    4 0.45 0.55 0.15
4    6 0.59 0.41 0.15
5    8 0.70 0.30 0.15
6   10 0.78 0.22 0.15
7   12 0.83 0.17 0.15</code></pre>
</div>
</div>
<p>The functions are plotted over a finer grid of times in Figure&nbsp;4. The cumulative incidence and survivor functions are probabilities, so are shown on a separate panel to the hazard, which is a rate.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb3-1">dense <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">data.frame</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">time =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">seq</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">by =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1</span>))</span>
<span id="cb3-2">dense<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>F_t <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pexp</span>(dense<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>time, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">rate =</span> rate)</span>
<span id="cb3-3">dense<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>S_t <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pexp</span>(dense<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>time, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">rate =</span> rate, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">lower.tail =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">FALSE</span>)</span>
<span id="cb3-4">dense<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>h_t <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> rate</span>
<span id="cb3-5"></span>
<span id="cb3-6">p_prob <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(dense, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> time)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb3-7">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_line</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> F_t, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">colour =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Cumulative incidence"</span>), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">linewidth =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.2</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb3-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_line</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> S_t, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">colour =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Survivor"</span>), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">linewidth =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.2</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb3-9">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_colour_manual</span>(</span>
<span id="cb3-10">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(</span>
<span id="cb3-11">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Cumulative incidence"</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> blog_cols[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"red"</span>]],</span>
<span id="cb3-12">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Survivor"</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> blog_cols[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"blue"</span>]]</span>
<span id="cb3-13">    )</span>
<span id="cb3-14">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb3-15">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">labs</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Time"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Probability"</span>)</span>
<span id="cb3-16"></span>
<span id="cb3-17">p_haz <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(dense, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> time, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> h_t)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb3-18">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_line</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">colour =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Hazard"</span>), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">linewidth =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.2</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">linetype =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"dashed"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb3-19">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_colour_manual</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Hazard"</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> blog_cols[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"green"</span>]])) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb3-20">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_y_continuous</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">limits =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3</span>)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb3-21">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">labs</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Time"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Hazard (events per unit time)"</span>)</span>
<span id="cb3-22"></span>
<span id="cb3-23">p_prob <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> p_haz</span></code></pre></div></div>
<div class="cell-output-display">
<div id="fig-survival-functions" class="quarto-float quarto-figure quarto-figure-center anchored" alt="Two panels. On the left, the cumulative incidence function rises from 0 towards 1 and the survivor function falls from 1 towards 0, crossing at around 4.6 units of time. On the right, the hazard is a flat dashed line at 0.15.">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-survival-functions-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://www.pkirwan.com/blog/survival-analysis/index_files/figure-html/fig-survival-functions-1.png" class="img-fluid figure-img" alt="Two panels. On the left, the cumulative incidence function rises from 0 towards 1 and the survivor function falls from 1 towards 0, crossing at around 4.6 units of time. On the right, the hazard is a flat dashed line at 0.15." width="672">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-survival-functions-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;4: Cumulative incidence and survivor functions (left), and the constant hazard (right), for an exponential model with a rate of 0.15 events per unit time.
</figcaption>
</figure>
</div>
</div>
</div>
<p>Here, the constant hazard demonstrates the “memoryless” property of the exponential model since the instantaneous risk does not depend on how long the individual has already survived.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
<span class="screen-reader-only">Note</span>Key takeaways
</div>
</div>
<div class="callout-body-container callout-body">
<ul>
<li>Survival analysis deals with “time-to-event” data, helping us understand <em>when</em> events happen, not just <em>if</em> they happen.</li>
<li>This approach handles incomplete information through concepts like censoring (when we have partial information) and truncation (when some subjects are never observed).</li>
<li>Standard statistical methods can’t properly handle censored data, which is why specialised survival analysis techniques are essential. These methods typically assume that censoring is independent of the event process.</li>
<li>The survivor function <img src="https://latex.codecogs.com/png.latex?S(t)"> gives the probability of not experiencing the event beyond time <img src="https://latex.codecogs.com/png.latex?t">.</li>
<li>The hazard function <img src="https://latex.codecogs.com/png.latex?h(t)"> represents the instantaneous rate of the event at time <img src="https://latex.codecogs.com/png.latex?t">, given survival up to that point.</li>
</ul>
</div>
</div>
</section>
<section id="coming-next" class="level2">
<h2 class="anchored" data-anchor-id="coming-next">Coming next</h2>
<p>In the next post, I’ll introduce the likelihood function and explore two classical methods for analysing survival data:</p>
<ul>
<li>The Kaplan-Meier estimator: a non-parametric approach to estimate survival probabilities;</li>
<li>The Cox proportional hazards model: a semi-parametric regression technique for examining covariate effects.</li>
</ul>
</section>
<section id="references" class="level2">
<h2 class="anchored" data-anchor-id="references">References</h2>
<ul>
<li>Collett D. <a href="https://www.taylorfrancis.com/books/mono/10.1201/9781003282525/modelling-survival-data-medical-research-david-collett">Modelling Survival Data in Medical Research</a>. <em>Chapman &amp; Hall/CRC Texts in Statistical Science</em>. 2023.</li>
<li>Klein JP, Moeschberger ML. <a href="https://play.google.com/store/books/details?id=KSq0e-6VFJ0C">Survival Analysis: Techniques for Censored and Truncated Data</a>. <em>Springer Science &amp; Business Media</em>; 2005.</li>
</ul>
<div class="post-navigation">
<p><a href="../../blog/key-concepts-infectious-disease/index.html">← Previous post</a></p>
<p><a href="../../index.html#blog">Back to all posts</a></p>
<p><a href="../../blog/classical-survival-methods/index.html">Next post →</a></p>
</div>


</section>

<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-reuse"><h2 class="anchored quarto-appendix-heading">Reuse</h2><div class="quarto-appendix-contents"><div><a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a></div></div></section><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre class="sourceCode code-with-copy quarto-appendix-bibtex"><code class="sourceCode bibtex">@online{kirwan2025,
  author = {Kirwan, Peter},
  title = {Part {II:} {Survival} Analysis},
  date = {2025-06-17},
  url = {https://www.pkirwan.com/blog/survival-analysis/},
  langid = {en}
}
</code></pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-kirwan2025" class="csl-entry quarto-appendix-citeas">
Kirwan, Peter. 2025. <span>“Part II: Survival Analysis.”</span> June 17.
<a href="https://www.pkirwan.com/blog/survival-analysis/">https://www.pkirwan.com/blog/survival-analysis/</a>.
</div></div></section></div> ]]></description>
  <category>Censoring</category>
  <category>Truncation</category>
  <guid>https://www.pkirwan.com/blog/survival-analysis/</guid>
  <pubDate>Tue, 17 Jun 2025 00:00:00 GMT</pubDate>
  <media:content url="https://www.pkirwan.com/blog/survival-analysis/survival-analysis-banner.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>Part I: Key concepts in infectious disease research</title>
  <dc:creator>Peter Kirwan</dc:creator>
  <link>https://www.pkirwan.com/blog/key-concepts-infectious-disease/</link>
  <description><![CDATA[ 






<p>This is part one of a series on statistical methods for infectious disease epidemiology, with a focus on time-to-event, or “survival”, data.</p>
<section id="epidemiological-measures" class="level2">
<h2 class="anchored" data-anchor-id="epidemiological-measures">Epidemiological measures</h2>
<p>Epidemiology is the study and analysis of patterns of diseases and determinants of health in a population. In the context of infectious diseases, epidemiologists and statisticians employ several standard measures of disease burden to assess the impact of a disease, and to guide the appropriate public health response. These measures include:</p>
<ul>
<li>the <strong>incidence of infection</strong>, defined as the rate of new infections occurring over a specific period of time, e.g.&nbsp;new cases per 1,000 people per year;</li>
<li>the <strong>prevalence of infection</strong>, defined as the proportion of the population that have the disease at a specific point in time, regardless of when they became infected;</li>
<li>for diseases with adverse outcomes, the <strong>mortality associated with infection</strong>, defined as the incidence of death from the disease.</li>
</ul>
<section id="r-number" class="level3">
<h3 class="anchored" data-anchor-id="r-number">The reproduction number</h3>
<p>A key measure of the spread of a disease, related to the incidence of infection, is the basic reproduction number, denoted <img src="https://latex.codecogs.com/png.latex?R_0">. The <img src="https://latex.codecogs.com/png.latex?R_0"> value measures the expected number of cases directly generated by one case in a population where all individuals are susceptible to infection.</p>
<p>For instance, if <img src="https://latex.codecogs.com/png.latex?R_0%20=%203"> for a particular disease then one infected individual will, on average, infect three others. When <img src="https://latex.codecogs.com/png.latex?R_0%20%3E%201"> an infection will spread in a population, whereas when <img src="https://latex.codecogs.com/png.latex?R_0%20%3C%201"> the disease will eventually die out.</p>
<p>Importantly, not every individual within a population will be equally susceptible to infection. Immunity to a pathogen might be acquired through vaccination or recovery from previous infection, both of which can provide a level of protection against future infections. Through widespread vaccination, immunity can be conferred to a large portion of a population, reducing susceptibility and thereby decreasing the number of new cases generated by each case. This is captured by the effective reproduction number, <img src="https://latex.codecogs.com/png.latex?R_t">, the expected number of cases directly generated by one case at time <img src="https://latex.codecogs.com/png.latex?t"> in a population where some individuals may no longer be susceptible, or where control measures are in place. Unlike <img src="https://latex.codecogs.com/png.latex?R_0">, <img src="https://latex.codecogs.com/png.latex?R_t"> changes over time.</p>
</section>
</section>
<section id="estimating-burden" class="level2">
<h2 class="anchored" data-anchor-id="estimating-burden">Estimating the burden of infectious disease</h2>
<p>To understand how quickly a virus is spreading through a population, and the corresponding burden of disease, timely and robust estimates are required. The incidence of new cases, prevalence of undiagnosed infection, and extent of disease severity can all inform policy makers seeking to implement effective and appropriate public health measures.</p>
<section id="incidence-and-prevalence" class="level3">
<h3 class="anchored" data-anchor-id="incidence-and-prevalence">Incidence and prevalence</h3>
<div id="fig-incidence-prevalence" class="quarto-float quarto-figure quarto-figure-center anchored" alt="Line chart of HIV prevalence and incidence in the US from 1980 to 2010. Active HIV/AIDS cases rise steadily to about 1.2 million, while new cases stay below about 150,000 per year">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-incidence-prevalence-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://www.pkirwan.com/blog/key-concepts-infectious-disease/incidence-prevalence.png" class="img-fluid figure-img" style="width:80.0%" alt="Line chart of HIV prevalence and incidence in the US from 1980 to 2010. Active HIV/AIDS cases rise steadily to about 1.2 million, while new cases stay below about 150,000 per year">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-incidence-prevalence-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;1: An example of the prevalence and incidence of HIV in the US over time. Incidence measures new cases over time, while prevalence measures total active cases at a specific point. Figure from: Steward K.
</figcaption>
</figure>
</div>
<p>Incidence of infection and the prevalence of an infectious disease in a population are generally unobserved, with observable information restricted to test outcomes among subsets of a population. Testing processes may themselves be influenced by unobserved parameters, such as an individual’s propensity to test, and the time from infection to symptom presentation (if symptoms present at all).</p>
<p>To reconstruct the incidence and prevalence of infection from the available testing data, statistical and mathematical modelling techniques which adjust for sampling biases are employed. These techniques combine information from a range of sources to make valid statistical inference about unobserved incidence and prevalence.</p>
</section>
<section id="severity" class="level3">
<h3 class="anchored" data-anchor-id="severity">Severity</h3>
<p>Two common metrics used to understand the severity of infectious diseases and the factors associated with adverse outcomes are the infection fatality risk (IFR) and case fatality rate (CFR). Both are proportions, although the CFR is conventionally called a “rate”:</p>
<ul>
<li><strong>Infection Fatality Risk (IFR)</strong>: The proportion of <em>all infected people</em> who die from the disease (including those whose infections were never detected)</li>
<li><strong>Case Fatality Rate (CFR)</strong>: The proportion of <em>confirmed cases</em> who die from the disease</li>
</ul>
<p>Since infections resulting in death are more likely to be recorded, and mild infections (particularly asymptomatic infections) less likely to be recorded, the CFR will almost always be higher than the IFR. Statistical modelling can be used to relate these measures of severity to underlying characteristics collected through case-surveillance data.</p>
</section>
<section id="effectiveness-of-interventions" class="level3">
<h3 class="anchored" data-anchor-id="effectiveness-of-interventions">Effectiveness of interventions</h3>
<p>Monitoring outcomes among a target group after the introduction of a public health intervention allows for the real-world effectiveness of the intervention to be assessed, and changes over time to be detected. For example, effectiveness estimates might consider reductions in the transmission or acquisition of an infection among a treated group compared to an untreated group. Making these estimates requires reliable testing data, recognition of potential biases, and methodologies which can account for these biases.</p>
</section>
<section id="challenges-in-estimating" class="level3">
<h3 class="anchored" data-anchor-id="challenges-in-estimating">Challenges in estimating infectious disease burden</h3>
<p>The majority of the data available for infectious disease monitoring relies on observational data, where a population is followed without actively intervening on an exposure in a randomised way. As a result, estimates of infectious disease burden are often considerably complicated by selection bias, which arises when the selected population observed is different from the general population of interest.</p>
<div id="fig-biases" class="quarto-float quarto-figure quarto-figure-center anchored" alt="Schematic of a hypothetical serosurvey. Recruitment at a grocery store (ascertainment bias) and testing of individuals with recent illness (volunteer bias) give a sample that over-represents infected individuals compared with the population of interest">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-biases-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://www.pkirwan.com/blog/key-concepts-infectious-disease/biases.webp" class="img-fluid figure-img" style="width:80.0%" alt="Schematic of a hypothetical serosurvey. Recruitment at a grocery store (ascertainment bias) and testing of individuals with recent illness (volunteer bias) give a sample that over-represents infected individuals compared with the population of interest">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-biases-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;2: Schematic showing recruitment-based biases in a hypothetical serosurvey. Figure from: Accorsi <em>et al.</em>
</figcaption>
</figure>
</div>
<p>Common causes of selection bias in observational data include: testing policies (which may vary nationally and sub-nationally), individual health-seeking behaviour, test availability, clinician decision-making, and detection rates of different tests. Inaccuracies in the available case-surveillance data may also arise: at data input, due to incomplete/inaccurate reporting or misdiagnosis; and at data collection, due to insufficient surveillance infrastructure and data processing methods.</p>
<p>Unless these potential sources of bias are well-understood and accounted for they can affect the validity of estimates. For example, the IFR measure of severity requires complete knowledge of both the number of infections and number of deaths. Particularly in the early stages of a pandemic, when testing is either unavailable or sub-optimal, these quantities may be impossible to measure. The CFR is more straightforward to assess, since confirmed infections are more likely to be recorded, but this measure is highly sensitive to testing practices. This was particularly the case during the initial wave of the COVID-19 pandemic, when biases in case-surveillance led to wide variability in national estimates of the case-fatality rate, from 0.1% to over 25% (World Health Organization, 2020).</p>
<p>Even when knowledge of these multi-faceted biases is available, statistical methodologies must be carefully chosen to properly control for the biases.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
<span class="screen-reader-only">Note</span>Key takeaways
</div>
</div>
<div class="callout-body-container callout-body">
<ul>
<li>Incidence of infection is the rate at which people acquire an infection over a given period, whereas prevalence is the proportion of the population who have the infection at one time.</li>
<li>The basic reproduction number, <img src="https://latex.codecogs.com/png.latex?R_0">, is the expected number of cases directly generated by one case in a fully susceptible population, whereas the effective reproduction number, <img src="https://latex.codecogs.com/png.latex?R_t">, allows for immunity and control measures changing over time.</li>
<li>There are various ways to assess the impact of a disease, these include incidence and prevalence, as well as disease severity and the effectiveness of interventions.</li>
<li>Measuring the burden of infectious disease using observational data is difficult and requires a special class of statistical methods.</li>
</ul>
</div>
</div>
</section>
</section>
<section id="coming-next" class="level2">
<h2 class="anchored" data-anchor-id="coming-next">Coming next</h2>
<p>In the next post I’ll provide an introduction to survival analysis, time-to-event data, and how we handle censored observations in epidemiological research.</p>
</section>
<section id="references" class="level2">
<h2 class="anchored" data-anchor-id="references">References</h2>
<ul>
<li>Accorsi EK, Qiu X, Rumpler E, <em>et al</em>. <a href="https://link.springer.com/article/10.1007/s10654-021-00727-7">How to detect and reduce potential sources of biases in studies of SARS-CoV-2 and COVID-19</a>. <em>Eur J Epidemiol.</em> 2021;36(2):179-96.</li>
<li>De Angelis D, Presanis AM, Birrell PJ, <em>et al</em>. <a href="http://dx.doi.org/10.1016/j.epidem.2014.09.004">Four key challenges in infectious disease modelling using data from multiple sources</a>. <em>Epidemics</em>. 2015;10:83-7.</li>
<li>Lipsitch M, Cohen T, Cooper B, <em>et al</em>. <a href="https://www.science.org/doi/10.1126/science.1086616">Transmission dynamics and control of severe acute respiratory syndrome</a>. <em>Science</em>. 2003;300(5627):1966-70.</li>
<li>Perez-Guzman PN, Knock E, Imai N, <em>et al</em>. <a href="http://dx.doi.org/10.1038/s41467-023-39661-5">Epidemiological drivers of transmissibility and severity of SARS-CoV-2 in England</a>. <em>Nat Commun</em>. 2023;14(1):4279.</li>
<li>Steward K. <a href="http://www.technologynetworks.com/immunology/articles/incidence-vs-prevalence-329073">Incidence vs Prevalence</a>. Immunology &amp; Microbiology from Technology Networks. Technology Networks; 2020.</li>
<li>Westreich D. <a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3237868/">Berkson’s bias, selection bias, and missing data</a>. <em>Epidemiology</em>. 2012;23(1):159-64.</li>
<li>World Health Organization. <a href="https://www.who.int/news-room/commentaries/detail/estimating-mortality-from-covid-19">Estimating mortality from COVID-19 (Scientific Brief)</a>. World Health Organization; 2020.</li>
</ul>
<p>For more details about key concepts in epidemiology and infectious disease research, see:</p>
<ul>
<li><a href="https://www.taylorfrancis.com/books/mono/10.1201/b16343/epidemiology-mark-woodward-mark-woodward">Epidemiology: Study design and data analysis</a> by Mark Woodward.</li>
</ul>
<div class="post-navigation">
<p><a href="../../index.html#blog">← Back to all posts</a></p>
<p><a href="../../blog/survival-analysis/index.html">Next post →</a></p>
</div>


</section>

<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-reuse"><h2 class="anchored quarto-appendix-heading">Reuse</h2><div class="quarto-appendix-contents"><div><a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a></div></div></section><section class="quarto-appendix-contents" id="quarto-citation"><h2 class="anchored quarto-appendix-heading">Citation</h2><div><div class="quarto-appendix-secondary-label">BibTeX citation:</div><pre class="sourceCode code-with-copy quarto-appendix-bibtex"><code class="sourceCode bibtex">@online{kirwan2025,
  author = {Kirwan, Peter},
  title = {Part {I:} {Key} Concepts in Infectious Disease Research},
  date = {2025-05-20},
  url = {https://www.pkirwan.com/blog/key-concepts-infectious-disease/},
  langid = {en}
}
</code></pre><div class="quarto-appendix-secondary-label">For attribution, please cite this work as:</div><div id="ref-kirwan2025" class="csl-entry quarto-appendix-citeas">
Kirwan, Peter. 2025. <span>“Part I: Key Concepts in Infectious Disease
Research.”</span> May 20. <a href="https://www.pkirwan.com/blog/key-concepts-infectious-disease/">https://www.pkirwan.com/blog/key-concepts-infectious-disease/</a>.
</div></div></section></div> ]]></description>
  <category>Incidence</category>
  <category>Prevalence</category>
  <category>Severity</category>
  <guid>https://www.pkirwan.com/blog/key-concepts-infectious-disease/</guid>
  <pubDate>Tue, 20 May 2025 00:00:00 GMT</pubDate>
  <media:content url="https://www.pkirwan.com/blog/key-concepts-infectious-disease/infectious-disease-banner.webp" medium="image" type="image/webp"/>
</item>
</channel>
</rss>
