1 Introduction

Considerable effort has been directed to track the severity and public health impact of coronavirus disease 2019 (Covid-19). Understanding the mortality impact of Covid-19 both over time and between countries is vital for distinguishing the relative effectiveness of different prevention and control measures, including vaccines. The efforts of individuals like John-Burn Murdoch, creator of the Financial Times’ coronavirus trajectory tracker charts,[1] are to be commended and have undoubtedly helped people attempt to make sense of what is happening in a fast-changing situation.

As the most direct indicator of mortality much attention has been given to the number of deaths caused by Covid-19; but within the field of public health there are established measures that can help provide a fuller picture of the mortality burden of Covid-19.

This report begins by explaining the different sources of information on Covid-19 deaths before comparing approaches to estimating ‘excess deaths’ — a better, more complete measure of the coronavirus pandemic’s overall mortality impact. In the second half of the report, we implement a set of actuarial and public health metrics — standardised death rates, years-of-life-lost and life expectancy — that offer a different perspective on the pandemic’s effect on population health.

# read data
govDths           <- readRDS(str_c(.datDir, "dat02_gov_daily_covidDths.RDS"))
wkDthsTot         <- readRDS(str_c(.datDir, "dat05_total_weekly_deaths_2010_to_2021.RDS"))
onsDths           <- readRDS(str_c(.datDir, "dat05_total_weekly_covidDths_2020_to_2021.RDS"))
wkDthsAgeGrp      <- readRDS(str_c(.datDir, "dat05_age_grp_weekly_deaths_2010_to_2021.RDS"))
covidAgeGrpDths   <- readRDS(str_c(.datDir, "dat05_age_grp_weekly_covidDths_2020_to_2021.RDS"))
xsDthsMod         <- readRDS(str_c(.datDir, "asis06_xs_deaths_model_results.RDS"))
xsDthsSimple      <- readRDS(str_c(.datDir, "asis06_xs_deaths_simple_counterfactuals.RDS"))
xsDthsSumTb       <- readRDS(str_c(.datDir, "asis06_xs_deaths_summary_table.RDS"))
xsDthsModAgeGrp   <- readRDS(str_c(.datDir, "asis06_xs_deaths_model_age_grp_results.RDS"))
xsDthsv2019AgeGrp <- readRDS(str_c(.datDir, "asis06_xs_deaths_v2019_age_grp.RDS"))
smr15to85         <- readRDS(str_c(.datDir, "asis07_smr15to85.RDS"))
rcSmr15to85       <- readRDS(str_c(.datDir, "asis07_rcSmr15to85.RDS"))
leSeries          <- readRDS(str_c(.datDir, "asis09_life_expectancy_2002_to_2019.RDS")) 
le2020            <- readRDS(str_c(.datDir, "asis09_life_expectancy_2020.RDS"))
yll_ls            <- readRDS(str_c(.datDir, "asis08_years_of_life_lost.RDS"))

# values used in text
yx2020CovidDths   <- onsDths %>% filter(isoYr == 2020) %>% summarise(dths = sum(dths)) %>% pull()
yx2020Dths        <- wkDthsTot %>% filter(isoYr == 2020) %>% summarise(dths = sum(dths)) %>% pull()
yx2020CovidDthsPc <- scales::percent(yx2020CovidDths / yx2020Dths, accuracy = .1)
qxSmrMaxWk        <- smr15to85 %>% filter(qxSmr == max(qxSmr, na.rm = TRUE)) %>% pull(isoWk)
qxSmrMaxWkEndDt   <- smr15to85 %>% filter(qxSmr == max(qxSmr, na.rm = TRUE)) %>% pull(isoYrWk)
qxSmrMaxWkEndDt   <- ISOweek::ISOweek2date(str_c(qxSmrMaxWkEndDt, 5, sep = "-"))
qxSmrMaxWkEndDt   <- paste(day(qxSmrMaxWkEndDt), months(qxSmrMaxWkEndDt), year(qxSmrMaxWkEndDt))
totCovidDths      <- round(xsDthsSumTb %>% filter(wave == "Total") %>% pull(dths19), -2)
yllTot            <- round(yll_ls[[1]] %>% summarise(yll = sum(yll)) %>% pull(yll), -2)
le20F             <- le2020 %>% filter(gender == "f") %>% pull(expBirth)
le20M             <- le2020 %>% filter(gender == "m") %>% pull(expBirth)
le20FChg          <- abs(le2020 %>% filter(gender == "f") %>% pull(expBirth)
                         - leSeries %>% filter(year == "2019", gender == "f") %>% pull(expBirth))
le20MChg          <- abs(le2020 %>% filter(gender == "m") %>% pull(expBirth)
                         - leSeries %>% filter(year == "2019", gender == "m") %>% pull(expBirth))

pct75Plus <- covidAgeGrpDths %>%
  group_by(ageGrp) %>%
  summarise(dths = sum(dths)) %>%
  mutate(csDths = cumsum(dths)) %>%
  mutate(csPct = csDths / sum(dths)) %>%
  filter(ageGrp == "70-74") %>%
  mutate(pct75Plus = 1 - csPct) %>%
  pull(pct75Plus)

pct75Plus <- scales::percent(pct75Plus, accuracy = 1)

2 How many people have died from Covid-19?

The infection fatality ratio (IFR — the proportion of those infected who will go on to die from that infection) is a key statistic for estimating the burden of Covid-19. Estimates have continuously been updated throughout the current pandemic. The overall IFR will vary across different populations as it depends on factors such as the age distribution of the population, the distribution of infection across age groups, and access to healthcare resources.

After reviewing multiple seroprevalence studies (where blood tests are used to identify how many people have antibodies against the SARS-CoV-2 virus) from different countries the Covid-19 response team at Imperial College estimated the overall IFR for a typical high income country, with a greater concentration of elderly individuals, to be 1.15% (0.78–1.79 95% prediction interval range).[2] Over time improvements in care and potential genetic mutations in the virus[3] have the potential to alter the IFR.

2.1 Covid-19 deaths data

There are two broad ways of counting Covid-19 deaths in the UK:

  • statistics reported through health and care organisations, usually focused on cases where a positive test for Covid-19 has been confirmed; and
  • statistics reported through the process of death registration, where Covid-19 appears on the death certificate.

Differences in the timeliness and coverage of these sources were not always well explained and changes to the methodology used by the government for daily surveillance reporting did not help in this regard.

The main sources of Covid-19 deaths data are:

  1. Public Health England (PHE) publish daily surveillance figures on deaths of people who died within 28 days of a first positive test for Covid-19.[4] The daily number represents new deaths reported to PHE by public health bodies in the 24 hours up to 5pm the previous day. From 29th April 2020, these are based (for England) on improved data, which provide a count of all deaths where a positive test for Covid-19 has been confirmed, wherever the death took place. Prior to this, the series did not include those who died outside of hospital settings e.g. in a care home. The 28-day cut-off was only introduced in August, before this time PHE reported deaths of all people with a confirmed positive test at any point since the start of the pandemic.
  2. NHS England (NHSE) publish a daily count of people who died in hospitals in England and had either tested positive for Covid-19 or where Covid-19 was mentioned on the death certificate.[5] The daily count contains deaths from the latest reporting period, 4pm two days prior to publication until 4pm the day before publication. From 28th April 2020, this series changed to include deaths where Covid-19 was mentioned on the death certificate. These figures do not include deaths outside hospital, such as those in care homes.
  3. The Office for National Statistics (ONS) publish weekly deaths data for England and Wales, released every Tuesday at 9:30am for the week that ended 11 days prior (for example, data for the week ending 20th March 2020 were released on 31st March 2020).[6] These are based on registrations of deaths where confirmed or suspected Covid-19 was mentioned on the death certificate, wherever the death took place. Death certification as involving Covid-19 does not depend on a positive test.

These measures are collected for different purposes with different strengths and weaknesses. Counting deaths in people who have laboratory-confirmed infection does not require a judgement to be made about cause of death; this means figures can be collected more quickly, making it more useful for real-time surveillance.

Surveillance reporting, however, is not designed to provide definitive information on the significance of Covid-19 as a cause of individual deaths. For example, in the early stages of the pandemic, there were deaths where Covid-19 was suspected but not confirmed by testing; for some patients testing positive for Covid-19 may be incidental or even unconnected to the cause of death.

Mortality statistics published by the ONS rely on information recorded when deaths are certified and registered. These are published weekly but the death registration process means their availability is delayed. The certification of death includes a clinical assessment by a medical practitioner (often the patient’s GP) of the reason for death. Registrations of deaths where confirmed or suspected Covid-19 was mentioned on the death certificate provide the most objective measurement of deaths from Covid-19.

Prompt and accurate certification of death is essential as it serves a number of functions. In addition to providing the decedent’s family with a cause of death, it has critical administrative and epidemiologic applications. In the UK, a medical certificate of cause of death is set out in two parts, in accordance with World Health Organisation recommendations. In part one the completing doctor identifies the underlying cause of death as ‘a) the disease or injury which initiated the train of morbid events leading directly to death, or b) the circumstances of the accident or violence which produced the fatal injury.’ Any other diseases, injuries, conditions, or events that contributed to the death, but were not part of the direct sequence are captured in part two.

Most routine mortality statistics are based on the underlying cause, but the Covid-19 deaths numbers reported in the ONS weekly deaths data are for deaths ‘involving Covid-19’ — deaths that had Covid-19 mentioned anywhere on the death certificate, whether as an underlying cause or a contributory factor.

For a subset of these deaths Covid-19 will have been identified as the underlying cause. According to the ONS, in around 90% of all deaths with Covid-19 mentioned on the death certificate it is recorded as the underlying cause of death.[7] All ONS deaths data used in this report relate to this wider measure of deaths involving Covid-19.

In the calendar year 2020 there were 80,830 deaths involving Covid-19 — 13.2% of the total 614,114 deaths that occurred in England & Wales.

Figure 2.1 compares PHE daily surveillance counts with ONS death registrations. The PHE data is aggregated to the same weekly period as the registrations and the registrations have been shifted by one week to account for the period between death and registration (c.75% of deaths are registered within 7 calendar days).[8] In the early stages of the pandemic, PHE reporting was limited to deaths of patients testing positive that occurred in hospital. From the end of April, the surveillance and death registrations series track closely showing two distinct waves separated by a ‘Summer lull.’

onsDths <- onsDths %>% 
  rownames_to_column() %>%
  mutate(isZeroCnt = (dths == 0 & lag(dths, default = 0) == 0)) %>%
  filter(!isZeroCnt) %>% 
  mutate(wkEnding = ISOweek::ISOweek2date(str_c(isoYrWk, 5, sep = "-"))) %>% 
  select(-rowname)

wkEndingDts <- onsDths %>%
  select(wkEnding) %>%
  mutate(wkEndingDt = wkEnding) %>%
  distinct()

pheDths <- govDths %>% 
  left_join(wkEndingDts, by = c("date" = "wkEnding")) %>% 
  mutate(wkEnding = zoo::na.locf(wkEndingDt, fromLast = TRUE, na.rm = FALSE)) %>%
  filter(!is.na(wkEnding)) %>%  
  group_by(wkEnding) %>% 
  summarise(dths = sum(dths))

subtitle_lab <- "Covid-19 weekly death count, <span style='color:#ec6555;'>**death certification**</span><span style='color:#686f73;'> v. </span><span style='color:#5881c1;'>**surveillance**</span>"

ggplot() +
  geom_line(aes(x = wkEnding, y = dths, group = 1), data = pheDths, color = "#ec6555") +
  geom_line(aes(x = wkEnding, y = lead(dths, 1), group = 1), data = onsDths, color = "#5881c1") +
  scale_x_date(name = NULL, date_breaks = "1 month", date_labels = "%b"
               , limits = as_date(c("2020-02-29", "2021-05-07")), expand = c(0, 0)) +
  scale_y_continuous(name = NULL, breaks = seq(0, 8e3, by = 2e3), labels = scales::comma) +
  annotate("text", x = as.Date("2020-09-01"), y = 7800
           , label = "Deaths within 28 days\nof a positive test"
           , color = "#5881c1", size = 3.6, hjust = 0, vjust = 1) +
  annotate("text", x = as.Date("2020-05-01"), y = 7800
           , label = "Covid-19 on the death\ncertificate (lagged by 1\nweek)"
           , color = "#ec6555", size = 3.6, hjust = 0, vjust = 1) +
  annotate("text", x = as.Date("2020-09-01"), y = 6800
           , label = "Before the end of April\nsurveillance reporting\ndid not include deaths\noutside of hospital"
           , color = "#5881c1", size = 3.6, hjust = 0, vjust = 1) +
  labs(caption = "Sources: ONS weekly death registrations; PHE surveillance reporting."
       , subtitle = subtitle_lab) +
  theme(plot.subtitle = element_markdown())

Figure 2.1: Early in the pandemic, surveillance reporting did not include
deaths outside hospital

Early in the pandemic, surveillance reporting did not include <br> deaths outside hospital

2.2 Excess mortality

Excess mortality is a term used in epidemiology and public health that refers to the number of deaths from all causes during a crisis above and beyond what we would have expected to see under ‘normal’ conditions.[9]

Excess mortality or excess deaths is a more comprehensive measure of the overall impact of the coronavirus pandemic on deaths than the confirmed Covid-19 death count alone. In a pandemic, deaths can rise sharply, but causes are often inaccurately recorded, particularly when reliable tests are not widely available.

Excess deaths will capture Covid-19 deaths that were undiagnosed or not reported but will also include less direct effects of the virus, including:

  • deaths from other health conditions left untreated if the health system is overwhelmed by Covid-19 cases or by deliberate actions that prioritise patients with Covid-19 over those with other symptoms;
  • the mortality effects of societal responses to the pandemic, like social distancing; and
  • the secondary consequences of those responses, such as reduced economic activity.

These factors are summarised in Figure 2.2.

knitr::include_graphics(str_c(.figDir, "covid_effects.png"), dpi = 180)

Figure 2.2: Excess mortality is influenced by many factors

Excess mortality is influenced by many factors

The concept of excess deaths is especially useful when considering international comparisons. Excess deaths are measured relative to a benchmark of ‘normal’ deaths. Normal death rates reflect persistent factors that differ between countries such as the age composition of the population, the incidence of smoking and air pollution, the prevalence of obesity, poverty and inequality, and the quality of health service provision.

Excess death rates therefore account for heterogeneity between countries, which makes them the best way of picking up the differential effects of a pandemic. A number of statistical and media agencies have invested considerable resource in comparing the evolution of excess mortality across different countries, including the ONS, the Financial Times, the Economist, the New York Times, and EuroMOMO.[1013]

2.3 Measurement of ‘normal’ or expected deaths

Most national statistical agencies, including the ONS, publish averages of past ‘normal’ deaths alongside up-to-date actual death counts. The ONS use a five-year average of deaths in the corresponding week, but it could be a shorter or longer period or even deaths in the same week from the previous year.

While a five-year average is both transparent and simple to calculate it may not provide an unbiased counterfactual (how many deaths would have occurred under different circumstances) against which to compare current year deaths. A five-year average ignores trends in mortality rates, changes in population size and changes in population age structure. Total annual deaths in England & Wales for the five-year’s up to 2020 fluctuated between a low of 524 thousand (2016) and a high of 539 thousand (2018).

To understand the effect of these different choices and establish a plausible range for Covid-19 excess mortality, here we compare the results from three alternative methods for estimating ‘normal’ or expected deaths. Each method generates a different estimate of how many deaths might have occurred in the absence of the coronavirus pandemic.

Methods for estimating expected deaths

  1. A simple five-year average of deaths in the corresponding week.
  2. Deaths from the corresponding week in 2019.
  3. Fit a statistical model to deaths in previous years and use the model to predict ‘normal’ deaths.

Weekly death counts follow a strong seasonal pattern, with larger numbers of deaths seen around the start and end of each year. Deaths by date of registration will also be lower in weeks containing public holidays as Register Offices are closed so fewer deaths are registered; but unlike deaths by date of occurrence they are not subject to revision when new data is released hence our preference to use them in this analysis.

Like any real-world phenomena, the number of deaths each week are affected by random variation or noise from chance factors that cannot be identified. Probability theory can provide an estimate for the scale of chance variation. Count data, like weekly death numbers, typically follow a Poisson distribution. This means, for example, if we expect 10,000 deaths in an average week, then a deviation of +/– 200 in any individual week would not be unexpected. Over a longer period, numbers of deaths will be affected by changes in the size and age composition of the population as well as trends in mortality rates.

Figure 2.3 compares weekly deaths in 2020 and the first half of 2021 with levels for the previous five years. These are averaged to obtain our first estimate of ‘normal’ deaths against which to compare deaths during the pandemic.

plotDat <- wkDthsTot %>%
  filter(isoYr > 2014) %>% 
  mutate(
    yrGrp = case_when(isoYr < 2020 ~ "2015-2019", isoYr == 2020 ~ "2020", isoYr == 2021 ~ "2021")
    , isoYr = as.character(isoYr)) %>%
  select(-isoYrWk) %>% 
  bind_rows(
    wkDthsTot %>% 
      filter(isoYr > 2014, isoYr < 2020) %>% 
      group_by(isoWk) %>% 
      summarise(dths = mean(dths)) %>%
      mutate(isoYr = "mn5", yrGrp = "mean\n2015-19"))

subtitle_lab <- "Weekly all-cause death count, <span style='color:#686f73;'>**mean 2015&ndash;2019**</span><span style='color:#686f73;'>, </span><span style='color:#ec6555;'>**2020**</span><span style='color:#686f73;'> and </span><span style='color:#b72614;'>**2021**</span>"

ggplot(plotDat) +
    geom_line(aes(x = isoWk, y = dths, group = isoYr, color = yrGrp)
            , show.legend = FALSE
            , data = plotDat %>% filter(yrGrp %in% c("2015-2019"))) +
  geom_line(aes(x = isoWk, y = dths, group = isoYr, color = yrGrp)
            , show.legend = FALSE
            , data = plotDat %>% filter(!yrGrp %in% c("2015-2019"))) +
  # geom_dl(aes(x = isoWk, y = dths, group = isoYr, color = yrGrp, label = yrGrp)
  #         , method = list(dl.trans(x = x, y = y+.1), "top.points", cex = .8, hjust = 0)
  #         , data = plotDat %>% filter(yrGrp %in% c("mean\n2015-19", "2020", "2021"))) +
  scale_color_manual(values = c("#cccccc", "#ec6555", "#b72614", "#686f73")) +
  scale_x_continuous(name = NULL, breaks = seq(0, 50, 10)) +
  scale_y_continuous(name = NULL, limits = c(7e3, 22.5e3), breaks = c(8e3, 12e3, 16e3, 20e3)
                     , labels = scales::comma) +
  labs(caption = "Source: ONS weekly death registrations."
       , subtitle = subtitle_lab) +
  theme(plot.subtitle = element_markdown())

Figure 2.3: The numbers of all-cause deaths in Spring 2020 and Winter 2020-21
were dramatically increased compared with recent years

The numbers of all-cause deaths in Spring 2020 and Winter 2020-21 <br> were dramatically increased compared with recent years

Figure 2.4 compares deaths in 2020 and 2021 with deaths in 2019 (the last full year unaffected by Covid-19). Deaths in the early weeks of 2020, before the pandemic struck, were very similar to those from 2019.

plotDat <- wkDthsTot %>%
  filter(isoYr %in% c(2019, 2020, 2021)) %>%
  mutate(yrGrp = case_when(isoYr == 2020 ~ "2020", isoYr == 2021 ~ "2021", TRUE ~ "2019"))

subtitle_lab <- "Weekly all-cause death count, <span style='color:#686f73;'>**2019**</span><span style='color:#686f73;'>, </span><span style='color:#ec6555;'>**2020**</span><span style='color:#686f73;'> and </span><span style='color:#b72614;'>**2021**</span>"

ggplot(plotDat) +
  geom_line(aes(x = isoWk, y = dths, group = isoYr, color = yrGrp), show.legend = FALSE) +
  # geom_dl(aes(x = isoWk, y = dths, color = yrGrp, label = yrGrp)
  #         , method = list(dl.trans(x = x+.6, y = y-.3), "first.qp", cex = .8)) +
  scale_color_manual(values = c("#686f73", "#ec6555", "#b72614")) +
  scale_x_continuous(name = NULL, breaks = seq(0, 50, 10)) +
  scale_y_continuous(name = NULL, limits = c(7e3, 22.5e3), breaks = c(8e3, 12e3, 16e3, 20e3)
                     , labels = scales::comma) +
  labs(caption = "Source: ONS weekly death registrations."
       , subtitle = subtitle_lab) +
  theme(plot.subtitle = element_markdown())

Figure 2.4: Deaths in the early part of 2020 were very similar to levels in 2019

Deaths in the early part of 2020 were very similar to levels in 2019

Predicted weekly deaths generated from our statistical model are shown in Figure 2.5. The model used was a Poisson regression time-series model similar to the FluMOMO model1 widely used to estimate influenza-attributable mortality.[14]

plotDat <- wkDthsTot %>%
  filter(isoYr >= 2019) %>%
  select(isoYrWk, dths) %>%
  mutate(grp = "actual deaths") %>% 
  bind_rows(
    xsDthsMod %>%
      filter(isoYr >= 2019) %>%
      select(isoYrWk, glmFmFit) %>% 
      mutate(grp = "predicted deaths") %>% 
      rename(dths = glmFmFit))

ggplot(plotDat) +
  geom_line(aes(x = isoYrWk, y = dths, group = grp, color = grp), show.legend = FALSE) +
  scale_color_manual(values = c("#ec6555", "#686f73")) +
  scale_x_discrete(name = NULL, breaks = c("2019-W01", "2020-W01", "2021-W01")
                   , labels = c("2019", "2020", "2021")) +
  scale_y_continuous(name = NULL, breaks = c(8e3, 12e3, 16e3, 20e3)
                     , labels = scales::comma, limits = c(7e3, 22.5e3)) +
  labs(caption = "Source: Strategy Unit analysis of ONS weekly death registrations."
       , subtitle = "Weekly all-cause death count, <span style='color:#ec6555;'>**actual** </span><span style='color:#686f73;'>and </span><span style='color:#686f73;'>**predicted deaths**</span>") +
  theme(plot.subtitle = element_markdown())

Figure 2.5: A statistical model can generate a prediction of ‘normal’ deaths
against which to measure the impact of the coronavirus pandemic

A statistical model can generate a prediction of 'normal' deaths <br> against which to measure the impact of the coronavirus pandemic

There is some uncertainty over when the first death from Covid-19 occurred. Following an inquest, a coroner announced in September that a patient in England died with Covid-19 in January 2020. Until then, the earliest known death involving Covid-19 was thought to be on 2nd March. For our excess deaths calculations, we take the start date of the pandemic to be week 10 (week ending 6th March, the first week in which the PHE data records a death within 28 days of a positive test for Covid-19).

To aid reporting, we have divided time since the pandemic began in to three periods to reflect two distinct waves of deaths separated by a ‘Summer lull.’

  1. A first wave that starts in week 10, the first week in which the PHE data records a death within 28 days of a positive test for Covid-19 (week ending 6th March, ONS weekly reporting ends on a Friday).
  2. A Summer lull starting in week 25 (w/e 19th June).
  3. A second wave from week 38 (w/e 18th September) to week 17 2021 (w/e 30th April).

Table 2.1 compares the estimates of excess deaths from our three alternative approaches. There is no definitive answer to which approach provides the most accurate estimate of the pandemic’s impact. However, we share the view of the Continuous Mortality Investigation (CMI) — a research organisation supported by the UK actuarial profession — that the similarity between mortality in early-2019 and early-2020 presents a strong case for favouring the use of 2019 deaths as the benchmark for expected deaths in 2020 and 2021.[15]

We estimate there have been 114,700 excess deaths in England & Wales from the start of the pandemic (by week 17 2021).

tabDat <- xsDthsSumTb %>% 
  select(wave, mn5, dths19, glmFmFit) %>%
  rename(`Method` = wave
         , `\\(2) Deaths from 2019` = dths19
         , `\\(1) Average deaths 2015-19` = mn5
         , `\\(3) Modelled deaths` = glmFmFit) %>%
  mutate_if(is.numeric, formatC, digits = 0, format = "f", big.mark = ",") %>% 
  rownames_to_column() %>%  
  pivot_longer(-rowname) %>% 
  pivot_wider(names_from = rowname, values_from = value) %>% 
  set_names(.[1,]) %>% 
  slice(-1)

tabDat %>% 
  kbl(align = c("l", rep("r", 4))
      , caption = "Different methods for estimating excess deaths arrive at broadly similar results") %>%
  kable_styling(full_width = FALSE, position = "left") %>% 
  column_spec(1, width = "14em") %>% 
  column_spec(2:5, width = "8em") %>% 
  footnote(general_title = ""
           , general = "Source: Strategy Unit analysis of ONS weekly death registrations."
           , footnote_as_chunk = TRUE)
Table 2.1: Different methods for estimating excess deaths arrive at broadly similar results
Method First wave Summer lull Second wave Total
(1) Average deaths 2015-19 55,715 -346 50,351 105,720
(2) Deaths from 2019 64,265 -1,336 51,807 114,736
(3) Modelled deaths 61,073 -140 55,451 116,384
Source: Strategy Unit analysis of ONS weekly death registrations.
  # save_kable(file = str_c(.figDir, "methods-xsdths-tab.png"))

2.4 How many excess deaths were directly caused by Covid-19?

There are good reasons why estimates of the number of excess deaths may differ from the counts of deaths where Covid-19 was mentioned on the death certificate.[15]

  • There may have been some deaths where Covid-19 was a contributory factor, but it was not mentioned on the death certificate. This is most likely to have occurred early in the pandemic.
  • Some deaths where Covid-19 was mentioned on the death certificate may not be ‘excess’ deaths, as the individual might have died from another cause in the same period, in the absence of coronavirus.
  • There may have been ‘forward mortality displacement’ — some deaths that occurred earlier in the pandemic would otherwise have occurred in this period.
  • There may have been indirect impacts on deaths due to restrictions on movement and changes in behaviour during the pandemic (e.g. inability to access needed healthcare, reduced transmission of other viruses, reduced injuries, increases in mental health disorders, or less exposure to high levels of pollution).

Figure 2.6 shows non-Covid deaths alongside total all-cause deaths. The only time non-Covid deaths were above normal levels was in March and April last year. It is likely, at least in part, this difference was due to under-reporting of deaths from Covid-19. From April 2020 onward non-Covid-19 deaths have been running below normal levels. It is difficult to be certain about why this is, but the increased size of the gap by the end of 2020 suggests there may have been some forward mortality displacement. That is, some of the people who died from Covid-19 in Spring 2020 would otherwise have died later in the year.

plotDat <- xsDthsSimple %>%
  select(-dths) %>%
  left_join(onsDths %>% rename(covDths = dths), by = c("isoYr", "isoWk", "isoYrWk")) %>% 
  left_join(xsDthsMod, by = c("isoYr", "isoWk", "isoYrWk")) %>%   
  mutate(nonCovidDths = case_when(dths - covDths == 0 ~ NA_real_, TRUE ~ dths - covDths)) %>% 
  select(isoYrWk, dths, dths19, nonCovidDths) %>%
  rename(total = dths, normal = dths19, `non-Covid` = nonCovidDths) %>% 
  pivot_longer(cols = total:`non-Covid`, names_to = "grp", values_to = "dths")

plotRect <- tibble(
  period = c("wave1", "wave2")
  , xmin = c("2020-W11", "2020-W39")
  , xmax = c("2020-W25", "2021-W17")
  , ymin = rep(6e3, 2)
  , ymax = rep(22.5e3, 2))

ggplot(plotDat) +
  geom_line(aes(x = isoYrWk, y = dths, group = grp, color = grp), show.legend = FALSE) +
  geom_rect(aes(xmin = xmin, ymin = ymin, xmax = xmax, ymax = ymax, fill = period)
            , show.legend = FALSE, color = NA, alpha = .2 
            , data = plotRect) +
  # geom_dl(aes(x = isoYrWk, y = dths, color = grp, label = grp)
  #         , method = list(dl.trans(x = x+.6, y = y-.3), "top.points", cex = .8)) +
  annotate("text", x = "2020-W18", y = 23.5e3
           , label = "First wave"
           , color = "#686f73", size = 3.5, hjust = 0.5, vjust = 1) +
  annotate("text", x = "2021-W02", y = 23.5e3
           , label = "Second wave"
           , color = "#686f73", size = 3.5, hjust = 0.5, vjust = 1) +
  scale_color_manual(values = c("#5881c1", "#686f73", "#ec6555")) +
  scale_fill_manual(values = rep("#f1b6ad", 2)) +
  scale_x_discrete(name = NULL, breaks = c("2020-W01", "2021-W01"), labels = c("2020", "2021")) +
  scale_y_continuous(name = NULL, breaks = c(8e3, 12e3, 16e3, 20e3), labels = scales::comma
                     , limits = c(6e3, 24e3)) +
  labs(caption = "Source: Strategy Unit analysis of ONS weekly death registrations."
       , subtitle = "Weekly death count, <span style='color:#5881c1;'>**non-Covid**</span><span style='color:#686f73;'>, </span><span style='color:#ec6555;'>**total**</span><span style='color:#686f73;'>, and <span style='color:#686f73;'>**normal**</span> deaths") +
  theme(plot.subtitle = element_markdown())

Figure 2.6: The only time non-Covid-19 deaths were consistently above normal levels was in Spring 2020

The only time non-Covid-19 deaths were consistently above normal levels was in Spring 2020

Figure 2.7 shows excess deaths overlaid with deaths from Covid-19. The numbers of deaths represented by the shaded areas are summarised in Table 2.2. In the first wave (ending in June 2020) there were 16,000 more excess deaths than deaths where Covid-19 was mentioned on the death certificate. In the second wave this relationship was reversed, and there were more Covid-19 deaths than excess deaths.

plotDat <- xsDthsSimple %>%
  select(-dths) %>%
  left_join(onsDths %>% rename(covDths = dths), by = c("isoYr", "isoWk", "isoYrWk")) %>% 
  left_join(xsDthsMod, by = c("isoYr", "isoWk", "isoYrWk")) %>%   
  mutate(nonCovidDths = case_when(dths - covDths == 0 ~ NA_real_, TRUE ~ dths - covDths)) %>% 
  mutate(excess = dths - dths19) %>%
  select(isoYrWk, covDths, excess) %>%
  rename(Covid = covDths) %>% 
  # geom_flame x must be continuous
  arrange(isoYrWk) %>% 
  group_by(isoYrWk) %>% 
  mutate(tm = cur_group_id())

plotRect <- tibble(
  period = c("wave1", "wave2")
  , xmin = c(11, 39)
  , xmax = c(25, 70)
  , ymin = rep(-3e3, 2)
  , ymax = rep(15e3, 2))

ggplot(plotDat) +
  geom_flame(aes(x = tm, y = Covid, y2 = .1), fill = "#ec6555", color = NA, alpha = .5) +
  geom_flame(aes(x = tm, y = excess, y2 = 0), fill = "#5881c1", color = NA, alpha = .5) +
  geom_flame(aes(x = tm, y = 0, y2 = excess), fill = "#5881c1", color = NA, alpha = .5) +
  geom_rect(aes(xmin = xmin, ymin = ymin, xmax = xmax, ymax = ymax, fill = period)
            , show.legend = FALSE, color = NA, alpha = .2 
            , data = plotRect) +
  scale_fill_manual(values = rep("#f1b6ad", 2)) +
  scale_x_continuous(name = NULL, breaks = c(1, 54), labels = c("2020", "2021")) +
  scale_y_continuous(name = NULL, breaks = c(seq(0, 15e3, by = 5e3)), labels = scales::comma) +
  annotate("text", x = 18, y = 16e3
           , label = "First wave"
           , color = "#686f73", size = 3.5, hjust = 0.5, vjust = 1) +
  annotate("text", x = 54, y = 16e3
           , label = "Second wave"
           , color = "#686f73", size = 3.5, hjust = 0.5, vjust = 1) +
  labs(caption = "Source: Strategy Unit analysis of ONS weekly death registrations."
       , subtitle = "Weekly death count, <span style='color:#5881c1;'>**excess deaths** </span><span style='color:#686f73;'>and </span><span style='color:#ec6555;'>**Covid-19 deaths**</span>") +
  theme(plot.subtitle = element_markdown())

Figure 2.7: During the second wave excess deaths were lower than deaths from Covid-19

During the second wave excess deaths were lower than deaths from Covid-19
tabDat <- xsDthsSumTb %>%
  filter(wave != "Total") %>% 
  select(wave, dths19) %>%
  rename(`Excess deaths` = dths19) %>%
  left_join(
    onsDths %>% 
    left_join(waves, by = c("isoYr", "isoWk")) %>% 
    group_by(wave) %>% 
    summarise(dths = sum(dths)) %>% 
    rename(`Covid-19 deaths` = dths)
    , by = "wave") %>% 
  mutate_if(is.numeric, formatC, digits = 0, format = "f", big.mark = ",") %>%
  pivot_longer(cols = -wave) %>% 
  pivot_wider(id_cols = name, names_from = "wave", values_from = "value") %>% 
  rename(` ` = name)

tabDat$` `[2] <- str_c(tabDat$` `[2], footnote_marker_alphabet(1))

tabDat %>% 
  kbl(align = c("l", rep("r", 4))
      , caption = "In the first wave there were more excess deaths than Covid deaths; this relationship reversed in the second wave"
      # remember this escape = F
      , escape = FALSE) %>%
  kable_styling(full_width = FALSE, position = "left") %>%
  column_spec(1, width = "14em") %>% 
  column_spec(2:4, width = "8em") %>% 
  footnote(general_title = ""
           , general = str_c("^a^", " Deaths where Covid-19 was mentioned on the death certificate.\nSource: Strategy Unit analysis of ONS weekly death registrations.")
           , footnote_as_chunk = TRUE)
Table 2.2: In the first wave there were more excess deaths than Covid deaths; this relationship reversed in the second wave
First wave Summer lull Second wave
Excess deaths 64,265 -1,336 51,807
Covid-19 deathsa 48,218 3,699 85,968
a Deaths where Covid-19 was mentioned on the death certificate.
Source: Strategy Unit analysis of ONS weekly death registrations.
  # save_kable(file = str_c(.figDir, "xsDths-tab.png"))

Since the start of the pandemic, there has been a strong age gradient to cumulative excess deaths, and deaths have been much higher among men than women (see Figure 2.8). This fits with what we know about Covid-19 that risk of dying from the virus climbs steeply with age and that men face a higher risk than women.[16] The lines for men and women are reversed for the 85+ age group because women’s greater life expectancy means that in the oldest age groups they outnumber men and there are more of them at risk of contracting Covid-19.

plotDat <- xsDthsv2019AgeGrp %>% 
  # filter(!(isoYr == 2020 & isoWk < 10)) %>%
  arrange(isoYrWk) %>% 
  group_by(gender, ageGrp) %>% 
  mutate(cumXsDths = cumsum(xsDths)) %>% 
  ungroup()

lab <- "Cumulative excess deaths: <span style='color:#5881c1;'>**men** </span><span style='color:#686f73;'>& </span><span style='color:#ec6555;'>**women**</span>"

# add "no_display" to years you don't want labelled
plotDat <- plotDat %>%
  mutate(isoYrWk = if_else(
    as.numeric(factor(ageGrp)) %% 2 != 0, as.character(isoYrWk), 
                              paste0(as.character(isoYrWk), "_no_display")))

# function to suppress labels
delete_no_display <- function(x) {
  if_else(str_detect(x, "_no_display"), "", str_replace(x, "-W[0-9]{2}", ""))
  # if_else(str_detect(x, "_no_display"), "", str_replace(x, "^.*[0-9]{2}([0-9]{2})(-W)([0-9]{2}).*", "\\1-Wk\\3"))
}

ggplot(plotDat) +
  # geom_line(aes(x = isoYrWk, y = cumXsDths, group = gender, color = gender), show.legend = FALSE) +
  geom_point(aes(x = isoYrWk, y = cumXsDths, group = gender, color = gender), size = 1, show.legend = FALSE) +
  facet_wrap(vars(ageGrp), nrow = 1, scales = "free_x") +
  scale_color_manual(values = c("#ec6555", "#5881c1")) +
  scale_x_discrete(name = NULL, breaks = c("2020-W01", "2021-W01"), labels = delete_no_display, expand = c(0, 2)) +
  scale_y_continuous(name = NULL, breaks = seq(0, 25e3, by = 5e3), labels = scales::comma, limits = c(-1000, 26e3)) +
  labs(caption = "Source: Strategy Unit analysis of ONS weekly death registrations.", tag = lab) +
  theme(strip.background = element_rect(fill = "#f8f8f7", colour = "#f8f8f7")
        , strip.text = element_text(size = rel(.8), hjust = .5, vjust = .5, margin = margin(t = 4, b = 4))
        , plot.tag = element_markdown(size = rel(.8), hjust = 0, vjust = 1, color = "#686f73", lineheight = 1.2)
        , plot.tag.position = c(.07, .86))

Figure 2.8: There is a steep age gradient to cumulative excess mortality

There is a steep age gradient to cumulative excess mortality

4 How many years of life have been lost to Covid-19?

Most estimates of the effect of Covid-19 on population health have focused on numbers of deaths. Perhaps because the majority of people dying from Covid are older with underlying long-term conditions (LTCs), some commentators have argued that victims of Covid-19 would have likely died anyway within a short timeframe.

… by the end of the year what proportion of people who died from Covid‑19 would have died anyhow? It might be as much as half to two thirds of the deaths we are seeing from Covid‑19 because it affects particularly people who are either at the end of their life or with prior health conditions.[18]
~ Professor Neil Ferguson, House of Commons Science and Technology Committee, 25th March 2020

treemapDat <- covidAgeGrpDths %>%
  group_by(ageGrp) %>% 
  summarise(dths = sum(dths))

ggplot(treemapDat, aes(area = dths, fill = ageGrp, label = ageGrp)) +
  geom_treemap(layout = "squarified", show.legend = FALSE) +
  geom_treemap_text(
    layout = "squarified"
    , fontface = "plain", colour = "white"
    , place = "centre", grow = FALSE, reflow = TRUE) +
  scale_fill_viridis_d(name = NULL, option = "D", direction = -1L, guide = guide_legend(reverse = TRUE)) +
  labs(caption = "Source: ONS, weekly death registrations."
      , subtitle = "Deaths from Covid-19 by age group") +
  theme(plot.subtitle = element_text(margin = margin(b = 12, unit = "pt")))

Figure 4.1: 73% of deaths involving Covid-19 have been among those aged 75 years and older

73% of deaths involving Covid-19 have been among those aged 75 years and older

However, while old-age and the presence of multiple LTCs is associated with raised mortality the average 80-year-old male can still expect another 8.7 years of life; for women it is another 10 years.[19]

A truer measure of the overall burden of Covid-19 on population mortality is years of potential life lost. Years of life lost (YLL) is a summary measure of premature mortality often used in public health planning to compare the relative burden of mortality from different diseases or to allow fair comparison of the impact of different health policies.

At the level of the individual, YLL is calculated as time lost based on the difference between age at death and the standard life expectancy at that age (obtained from life tables). For example, a woman dying at age 65 loses 21 years of potential life — the conditional life expectancy for a female having reached age 65 is 86.[19]

Following the conventional approach to estimating YLL, we used relative frequencies on the age at which deaths from Covid-19 occurred combined with typical life expectancy at a given age (from standard life tables) to estimate a weighted average loss associated with a Covid-19 death in England & Wales (see Table 4.1). For broad UK comparisons, total YLL from stroke was estimated at 626 thousand by the Global Burden of Disease study in 2019.

Using standard life tables for England & Wales, we estimate 1.43 million years of life have been lost to Covid (week 17 2021).

In using national life tables, we have implicitly assumed that the comorbidity burden by age among Covid-19 victims is similar to that of the general population. This is a standard assumption when calculating YLL by cause. Here, it is important to remember that among the age groups most affected by Covid, many people will have some form of ‘existing condition.’ For example, the 2019 Health Survey for England shows that among those aged 75 and over, 66% have hypertension, 22% have diabetes, and 26% are obese.[20]

Adjusting for the number and type of underlying conditions is, however, technically difficult and requires good estimates of co-morbidity among Covid-19 victims as well as survival data for the reference population.

Combining data on the prevalence and co-occurrence of long-term conditions among a cohort of patients who had died from Covid-19 in Italy with information on survival from a UK research database researchers were able to estimate YLL accounting for number and type of underlying LTC.[21] They found mean YLL remained high even after adjustment for number and type of LTCs — 11.6 and 9.4 years for men and women, respectively, compared to 14 and 12 years before adjustment.

dthsWv <- onsDths %>%
  left_join(waves, by = c("isoYr", "isoWk")) %>% 
  group_by(wave) %>% 
  summarise(dths = sum(dths)) %>% 
  mutate(dths = prettyNum(formatC(dths, digits = 0, format = "f", big.mark = ","))) %>% 
  rename(Deaths = dths)

yllWv <- yll_ls[[1]] %>% 
  group_by(wave) %>% 
  summarise(yll = sum(yll)) %>% 
  mutate(yll = prettyNum(formatC(yll, digits = 0, format = "f", big.mark = ","))) %>% 
  rename(`Years of life lost` = yll)

mnYllWv <- yll_ls[[2]] %>% 
  mutate(mnYll = prettyNum(formatC(mnYll, digits = 1, format = "f"))) %>% 
  rename(`Mean YLL` = mnYll)

dthsAndYll <- dthsWv %>%
  left_join(yllWv, by = "wave") %>%
  left_join(mnYllWv, by = "wave") %>% 
  pivot_longer(-wave, "measure", "value") %>%
  pivot_wider(measure, wave)

dthsTot <- onsDths %>%
  summarise(dths = sum(dths)) %>% 
  mutate(dths = prettyNum(formatC(dths, digits = 0, format = "f", big.mark = ","))) %>% 
  rename(Deaths = dths)

yllTot <- yll_ls[[1]] %>% ungroup() %>%  
  summarise(yll = sum(yll)) %>% 
  mutate(yll = prettyNum(formatC(yll, digits = 0, format = "f", big.mark = ","))) %>% 
  rename(`Years of life lost` = yll)

mnYllTot <- yll_ls[[3]] %>% 
  mutate(mnYll = prettyNum(formatC(mnYll, digits = 1, format = "f"))) %>% 
  rename(`Mean YLL` = mnYll)

dthsAndYllTot <- tibble(dthsTot, yllTot, mnYllTot) %>%
  mutate(wave = "Total") %>% 
  pivot_longer(-wave, "measure", "value") %>%
  pivot_wider(measure, wave)

dthsAndYllTbl <- dthsAndYll %>%
  left_join(dthsAndYllTot, by = "measure")

dthsAndYllTbl$measure[1] <- str_c(dthsAndYllTbl$measure[1], footnote_marker_alphabet(1))

dthsAndYllTbl %>%
  select(measure, `First wave`, `Summer lull`, `Second wave`, Total) %>%
  rename(` ` = measure) %>% 
  kbl(align = c("l", rep("r", 4))
      , caption = "Deaths and estimated years of life lost from Covid-19"
      # remember this escape = F
      , escape = FALSE) %>%
  kable_styling(full_width = FALSE, position = "left") %>%
  column_spec(1, width = "14em") %>% 
  column_spec(2:5, width = "8em") %>% 
  footnote(general_title = ""
           , general = str_c("^a^", " Deaths where Covid-19 was mentioned on the death certificate.\nSource: Strategy Unit analysis."), footnote_as_chunk = TRUE)
Table 4.1: Deaths and estimated years of life lost from Covid-19
First wave Summer lull Second wave Total
Deathsa 48,218 3,699 85,968 137,885
Years of life lost 488,778 37,668 903,175 1,429,622
Mean YLL 10.1 10.2 10.5 10.4
a Deaths where Covid-19 was mentioned on the death certificate.
Source: Strategy Unit analysis.
  # save_kable(file = str_c(.figDir, "yll-tab.png"))

From early in the pandemic, the intensive care national audit and research centre (ICNARC) has issued regular reports of data on patients critically ill with confirmed Covid-19 covering all NHS adult intensive care units (ICU) in England, Wales and Northern Ireland. While there is a need to be careful about drawing conclusions from ICU admissions, which are a subset of Covid-19 cases, these reports include useful information about the medical histories of Covid-19 patients. To the end of August 2020, there had been almost 11 thousand admissions of confirmed Covid-19 patients to ICU. Nine in ten of these patients were able to live without assistance in daily activities prior to admission to hospital and only one in ten had very severe comorbidities.[22] When compared to a historical cohort of patients critically ill with viral pneumonia Covid-19 patients were healthier on both measures (see Table 4.2). Mortality at the end of critical care among the Covid-19 group was 39.4% — although this dropped to 27.8% in the second wave — compared with 21.4% for the viral pneumonia patients.

icnarcMeasures <- tibble(
  Measure = c("Age (years)", "Live without assistance (%)", "Severe comorbidities (%)", "Death at end of critical care (%)")
  , `Covid-19 wave 1` = c(58.8, 89.4, 10.0, 39.4)
  , `Covid-19 wave 2` = c(60.0, 88.1, 9.2, 27.8)
  , `Viral pneumonia` = c(58.0, 73.6, 24.0, 21.4))

icnarcMeasures %>%
  rename(` ` = Measure) %>% 
  kbl(align = c("l", rep("r", 3))
      , caption = "Before admission patients critically ill with Covid-19 were healthier than patients with viral pneumonia") %>%
  kable_styling(full_width = FALSE, position = "left") %>%
  column_spec(1, width = "16em") %>% 
  column_spec(2:4, width = "10em") %>% 
  footnote(general_title = ""
           , general = "Source: ICNARC reporting on Covid-19 in critical care."
           , footnote_as_chunk = TRUE)
Table 4.2: Before admission patients critically ill with Covid-19 were healthier than patients with viral pneumonia
Covid-19 wave 1 Covid-19 wave 2 Viral pneumonia
Age (years) 58.8 60.0 58.0
Live without assistance (%) 89.4 88.1 73.6
Severe comorbidities (%) 10.0 9.2 24.0
Death at end of critical care (%) 39.4 27.8 21.4
Source: ICNARC reporting on Covid-19 in critical care.
  # save_kable(file = str_c(.figDir, "icnarc-tab.png"))

Some vulnerable individuals who died of Covid-19 might otherwise have died from alternate causes: a concept known as ‘mortality displacement.’ If the residual life expectancy for a significant number of Covid-19 victims was no longer than several months, then one might expect to find evidence of mortality displacement in aggregate mortality data. This would most likely appear as a compensatory period of lower-than-expected mortality from other causes.

While age-standardised mortality rates did fall to historic lows during the third quarter of 2020 the scale of reduction was small compared to the extent of the spring peak. More recently, during the second wave, non-Covid deaths (see Figure 2.6) have been lower than would have been expected in the absence of the pandemic. Again, this observation is consistent with some mortality displacement but is not of a scale that suggests large numbers of people dying in the first wave would otherwise have succumbed to other causes within a very short time frame.

5 What has been the effect of Covid-19 on life expectancy?

Life expectancy at birth is another commonly used indicator of population health. Period life expectancy is the average number of years a hypothetical newborn is expected to survive if their entire life, from birth to death, is lived under the mortality conditions prevailing in the current year.

Figure 5.1 shows that following an extended period of steady increases, the rate of improvement in life expectancy slowed from around 2011. The most recent national statistics put life expectancy at birth in England & Wales at 79.8 years for men and 83.5 years for women (these figures precede any effect of the coronavirus pandemic).[19]

We estimated life expectancy at birth for England & Wales for the calendar year 2020 by aggregating ONS age-group weekly death registrations and calculating death rates using a mid-2020 population estimate. Life expectancy in 2020 was 78.5 years for men and 82.5 years for women — a reduction of 1.3 years and 1.0 years, respectively. However, in the context of epidemic mortality it should be remembered that the calculation of period life expectancy at birth implicitly assumes the epidemic is experienced in all future years as a person ages.

gender_label <- c("f" = "Women", "m" = "Men")

leSeriesPlotDat <- leSeries %>%
  mutate(grp = "true") %>% 
  bind_rows(le2020 %>% mutate(grp = "est")) %>% 
  mutate(gender = factor(gender, levels = c("m", "f")))

ggplot(leSeriesPlotDat) +
  geom_line(aes(x = year, y = expBirth, group = 1), color = "#5881c1") +
  geom_point(aes(x = year, y = expBirth, group = 1), color = "#5881c1") +
  geom_point(aes(x = year, y = expBirth, group = 1)
             , color = "#ec6555"
             , data = leSeriesPlotDat %>% filter(year == "2020")) +
  scale_x_continuous(name = NULL, breaks = seq(2004,  2020, by = 4)) +
  scale_y_continuous(name = NULL) +
  facet_wrap(vars(gender), labeller = labeller(gender = gender_label)) +
  labs(caption = "Source: Strategy Unit analysis.") +
  theme(
    strip.text = element_text(size = rel(.8), hjust = .5, vjust = .5, margin = margin(t = 4, b = 4))
    , strip.background = element_rect(fill = "#f8f8f7", colour = "#f8f8f7"))

Figure 5.1: Life expectancy in 2020 fell by 1.0 years for women and 1.3 years for men

Life expectancy in 2020 fell by 1.0 years for women and 1.3 years for men

6 Endnotes

7 References

1
Coronavirus trajectory tracker explained. https://www.ft.com/video/9a72a9d4-8db1-4615-8333-4b73ae3ddff8 (accessed 26 May 2021).
2
Report 34 - COVID-19 Infection Fatality Ratio Estimates from Seroprevalence. Imperial College London. http://www.imperial.ac.uk/medicine/departments/school-public-health/infectious-disease-epidemiology/mrc-global-infectious-disease-analysis/covid-19/report-34-ifr/ (accessed 27 May 2021).
3
Challen R, Brooks-Pollock E, Read JM, et al. Risk of mortality in patients infected with SARS-CoV-2 variant of concern 202012/1: Matched cohort study. BMJ 2021;372:n579. doi:10.1136/bmj.n579
4
Public Health England. Deaths within 28 days of positive test. Coronavirus (COVID-19) in the UK. 2021.https://coronavirus.data.gov.uk/ (accessed 1 Mar 2021).
5
NHS England. COVID-19 daily announced deaths. COVID-19 daily deaths. 2021.https://www.england.nhs.uk/statistics/statistical-work-areas/covid-19-daily-deaths/https://coronavirus.data.gov.uk/ (accessed 1 Mar 2021).
6
Office for National Statistics. Deaths registered weekly in England and Wales, provisional. Office for National Statistics. 2021.https://www.ons.gov.uk/peoplepopulationandcommunity/birthsdeathsandmarriages/deaths/datasets/weeklyprovisionalfiguresondeathsregisteredinenglandandwales (accessed 1 Mar 2021).
7
Quality of mortality data during the coronavirus pandemic, England and Wales - Office for National Statistics. https://www.ons.gov.uk/peoplepopulationandcommunity/birthsdeathsandmarriages/deaths/articles/qualityofmortalitydataduringthecoronaviruspandemicenglandandwales/2020 (accessed 26 May 2021).
8
Office for National Statistics. Impact of registration delays on mortality statistics in England and Wales: 2019. Office for National Statistics. 2020.https://www.ons.gov.uk/peoplepopulationandcommunity/birthsdeathsandmarriages/deaths/articles/impactofregistrationdelaysonmortalitystatisticsinenglandandwales/2019 (accessed 1 Mar 2021).
9
Checchi F, Roberts L. Interpreting and using mortality data in humanitarian emergencies A primer for non-epidemiologists. 2005.
10
Comparisons of all-cause mortality between European countries and regions - Office for National Statistics. https://www.ons.gov.uk/peoplepopulationandcommunity/birthsdeathsandmarriages/deaths/articles/comparisonsofallcausemortalitybetweeneuropeancountriesandregions/2020 (accessed 27 May 2021).
11
Coronavirus tracker: The latest figures as countries fight the Covid-19 resurgence Free to read Financial Times. https://www.ft.com/content/a2901ce8-5eb7-4633-b89c-cbdf5b386938 (accessed 27 May 2021).
12
Wu J, McCann A, Katz J, et al. The Pandemic’s Hidden Toll: Half a Million Deaths. The New York Timeshttps://www.nytimes.com/interactive/2020/04/21/world/coronavirus-missing-deaths.html (accessed 27 May 2021).
13
Graphs and maps from EUROMOMO. EUROMOMO. https://euromomo.eu/dev-404-page/ (accessed 27 May 2021).
14
Nielsen J, Krause TG, Mølbak K. Influenza-associated mortality determined from all-cause mortality, Denmark 2010/11-2016/17: The FluMOMO model. Influenza and Other Respiratory Viruses 2018;12:591–604. doi:10.1111/irv.12564
15
Continuous Mortality Investigation. England & Wales mortality monitor – COVID-19 update – week 36 of 2020. 2020.
16
Williamson EJ, Walker AJ, Bhaskaran K, et al. Factors associated with COVID-19-related death using OpenSAFELY. Nature 2020;584:430–6. doi:10.1038/s41586-020-2521-4
17
Mortality Projections Committee. Working Paper 111: Regular monitoring of England & Wales population mortality. Continuous Mortality Investigation, Institute; Faculty of Actuaries 2019.
18
Oral evidence from Professor Neil Ferguson. 2020;Q.28.
19
Single-year life tables, UK: 1980 to 2019 - Office for National Statistics. https://www.ons.gov.uk/peoplepopulationandcommunity/birthsdeathsandmarriages/lifeexpectancies/datasets/singleyearlifetablesuk1980to2018 (accessed 26 May 2021).
20
Health Survey for England 2019 [NS]. NHS Digital. https://digital.nhs.uk/data-and-information/publications/statistical/health-survey-for-england/2019 (accessed 12 Mar 2021).
21
Hanlon P, Chadwick F, Shah A, et al. COVID-19 – exploring the implications of long-term condition type and extent of multimorbidity on years of life lost: A modelling study. Wellcome Open Research 2021;5:75. doi:10.12688/wellcomeopenres.15849.3
22
Intensive Care National Audit & Research Centre. ICNARC report on COVID-19 in critical care. Intensive Care National Audit & Research Centre 2020.

  1. The model is a generalized linear model regression on weekly deaths assuming a Poisson distribution, adjusted for long-term trend and featuring trigonometric terms for the seasonal effect.↩︎

  2. As far as is possible, we followed the methods described by the CMI. Any differences between the charts in this section and similar charts published by the CMI likely reflect small differences in population exposure calculations for the most recent years.↩︎