Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Calculate the age-stratified IFR based on the Spanish serosurvey of 60897 participants
#!/usr/bin/python3
#
# Calculate the age-stratified IFR based on the Spanish serosurvey of 60897 participants.
#
# Author: Marc Bevand — @zorinaq
# Population pyramid for Spain (age 0 to 100)
# https://worldpopulationreview.com/countries/spain-population/
# Hack to extract the raw data: https://twitter.com/zorinaq/status/1265380966450622464
# pyramid[N] = number of people of age N
pyramid = [389071,395760,404555,414953,411842,432086,450617,467032,480928,493573,506233,510163,501625,485224,469003,450996,438622,436275,440530,443668,447359,450865,453090,454935,458810,464718,470848,476697,483276,491535,500604,515444,538403,566972,594959,622001,652353,686993,723042,757510,792033,815052,820836,814644,807993,799212,788640,777807,766575,752713,736006,722714,715523,711721,706221,700412,690511,674241,653635,633659,614107,592701,569064,544537,519985,494201,475071,466281,463940,460575,457809,451462,438746,421694,405814,390815,372987,351294,327555,303574,277747,258748,250683,249083,246213,244626,235612,214376,185512,155765,131040,113392,91852,66359,48324,40084,32862,24229,14184,8251,12310]
# Prevalence of antibodies by age bracket, in % (serosurvey dates: 27-April-2020 to 11-May-2020)
# https://www.mscbs.gob.es/gabinetePrensa/notaPrensa/pdf/13.05130520204528614.pdf
prevalence_by_age = {
(0,0): 1.1,
(1,4): 2.2,
(5,9): 3.0,
(10,14): 3.9,
(15,19): 3.8,
(20,24): 4.5,
(25,29): 4.8,
(30,34): 3.8,
(35,39): 4.6,
(40,44): 5.3,
(45,49): 5.7,
(50,54): 5.8,
(55,59): 6.1,
(60,64): 5.9,
(65,69): 6.2,
(70,74): 6.9,
(75,79): 6.1,
(80,84): 5.1,
(85,89): 5.6,
(90,199): 5.8,
}
# Total deaths and number of deaths by age bracket (as of 11-May-2020)
# https://www.mscbs.gob.es/profesionales/saludPublica/ccayes/alertasActual/nCov-China/documentos/Actualizacion_102_COVID-19.pdf
# The total for all age brackets (18722, table 3) differs from total deaths (26744, page 1)
# because age information is not always available, see table 3 header:
# «Distribución de casos hospitalizados, ingresados en UCI y fallecidos por grupos de edad y
# sexo información disponible»
deaths_by_age = {
(0,9): 2,
(10,19): 5,
(20,29): 23,
(30,39): 61,
(40,49): 197,
(50,59): 605,
(60,69): 1654,
(70,79): 4529,
(80,89): 7688,
(90,199): 3958,
(0,199): 18722,
}
total_deaths = 26744
def get_population(bracket):
'''Returns number of people in the given age bracket.'''
return sum(pyramid[bracket[0] : bracket[1] + 1])
def get_infected(bracket):
'''Returns number of infected people in the given age bracket.'''
i = 0
for age in range(bracket[0], bracket[1] + 1):
for (bracket2, percentage) in prevalence_by_age.items():
if age >= bracket2[0] and age <= bracket2[1] and age < len(pyramid):
i += pyramid[age] * percentage / 100.0
return i
for (bracket, deaths) in deaths_by_age.items():
n = get_population(bracket)
i = get_infected(bracket)
print('Ages {ages:7} {i:7} infected, {deaths:5} deaths, {ifr:6.3f}% IFR'.format(
ages='{}-{}:'.format(bracket[0], bracket[1]), i=int(i), deaths=deaths, ifr=100.0 * deaths / i))
total_infected = get_infected((0,199))
print('Overall: {i:7} infected, {deaths:5} deaths, {ifr:6.3f}% IFR'.format(
i=int(total_infected), deaths=total_deaths, ifr=100.0 * total_deaths / total_infected))
print('True IFR may be higher due to right-censoring and underreporting of deaths')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.