-
Notifications
You must be signed in to change notification settings - Fork 3
/
estimate_ascertainment.Rmd
188 lines (147 loc) · 6.72 KB
/
estimate_ascertainment.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
---
title: "Estimating the proportion of cases that are ascertained during an outbreak"
output:
bookdown::html_vignette2:
fig_caption: yes
code_folding: show
pkgdown:
as_is: true
bibliography: resources/library.json
link-citations: true
vignette: >
%\VignetteIndexEntry{Estimating the proportion of cases that are ascertained during an outbreak}
%\VignetteEncoding{UTF-8}
%\VignetteEngine{knitr::rmarkdown}
editor_options:
chunk_output_type: console
---
```{r setup, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
dpi = 300,
fig.width = 5, fig.height = 3
)
```
The ascertainment of cases during an outbreak is influenced by a multiple factor including testing capacity, the case definition, and sampling regime (e.g. symptom-based testing rather than random sampling).
`estimate_ascertainment()` offers a convenient way to calculate the proportion of cases that is ascertained using a cases and deaths time-series, a baseline "known" severity, and optionally a distribution of delays between case reporting and death.
The ascertainment ratio is calculated as the disease severity calculated from the data, divided by the "known" disease severity known or assumed from our best knowledge of the pathology of the disease.
`estimate_ascertainment()` uses `cfr_static()` internally to estimate the delay-adjusted severity of the disease.
::: {.alert .alert-warning}
New to calculating disease severity using _cfr_? You might want to see the ["Get started" vignette first](cfr.html).
:::
::: {.alert .alert-primary}
## Use case {-}
The **ascertainment of cases in an outbreak is not perfect**.
We want to estimate the proportion of cases being ascertained given case and death data.
:::
::: {.alert .alert-secondary}
### What we have {-}
* A time-series of cases and deaths, (cases may be substituted by another indicator of infections over time);
* Data on the distribution of delays, describing the probability an individual will die $t$ days after they were initially infected.
:::
```{r, message = FALSE, warning=FALSE, eval = TRUE}
# load {cfr} and data packages
library(cfr)
# packages to wrangle and plot data
library(dplyr)
library(tidyr)
library(purrr)
library(scales)
library(forcats)
library(ggplot2)
```
::: {.alert .alert-info}
**Note that** `estimate_static()` is used to generate a severity estimate which is compared against a 'known' severity estimate to calculate the ascertainment ratio.
See the [vignette on static severity estimation](estimate_static_severity.html) to learn more about how `estimate_static()` chooses a method for profile likelihood generation and hence CFR estimation.
:::
## Ascertainment for the Covid-19 pandemic in the U.K.
This example shows ascertainment ratio estimation using _cfr_ and data from the Covid-19 pandemic in the United Kingdom.
We load example Covid-19 daily case and death data provided with the _cfr_ package as `covid_data`, and subset for the first six months of U.K. data.
```{r}
# get Covid data provided with the package
data("covid_data")
# filter for the U.K
df_covid_uk <- filter(
covid_data,
country == "United Kingdom", date <= "2020-06-30"
)
# view the data format
tail(df_covid_uk)
```
We obtain the appropriate distribution reported in @linton2020; this is a log-normal distribution with $\mu$ = 2.577 and $\sigma$ = 0.440.
::: {.alert .alert-warning}
**Note that** @linton2020 fitted a discrete lognormal distribution --- but we use a continuous distribution here.
See the [vignette on delay distributions](delay_distributions.html) for more on when using a continuous instead of discrete distribution is acceptable, and on using discrete distributions with _cfr_.
**Note that** we use the central estimates for each distribution parameter, and by ignoring uncertainty in these parameters the uncertainty in the resulting CFR is likely to be underestimated.
:::
### Estimating the proportion of cases that have been ascertained
We use the `estimate_ascertainment()` function to calculate the static CFR (internally), and the overall ascertainment for the Covid-19 pandemic in the U.K.
We assume that the "true" CFR of Covid-19 is 0.014 (i.e. 1.4%) [@verity2020].
Future plans for this package include ability to incorporate uncertainty in CFR estimates when calculating under-ascertainment.
::: {.alert .alert-info}
**Note that** the CFR from @verity2020 is based on lab-confirmed and clinically diagnosed cases from Wuhan, China.
Since the case definition for the U.K. is different from that used here, the ascertainment ratio estimated is likely to be biased.
Furthermore, by ignoring uncertainty in this estimate, the ascertainment ratio is likely to be over-precise as well.
:::
```{r }
# static ascertainment on data
estimate_ascertainment(
data = df_covid_uk,
delay_density = function(x) dlnorm(x, meanlog = 2.577, sdlog = 0.440),
severity_baseline = 0.014
)
```
## Ascertainment in countries with large early Covid-19 pandemics
Finally, we estimate ascertainment for all countries with at least 100,000 reported Covid-19 deaths between 2020 and 2023, and focus on the period between the start of each outbreak to the 1st of June 2020.
We now use the larger dataset `covid_data` made available with the _cfr_ package.
We exclude four countries which only provide weekly data (with zeros for dates in between), and plot the ascertainment for each country remaining.
```{r warning=FALSE}
# countries with weekly reporting
weekly_reporting <- c("France", "Germany", "Spain", "Ukraine")
# subset for early covid outbreaks
covid_data_early <- filter(
covid_data, date < "2020-06-01",
!country %in% weekly_reporting
)
# nest the data
df_reporting <- nest(covid_data_early, .by = country)
# define density function
delay_density <- function(x) dlnorm(x, meanlog = 2.577, sdlog = 0.440)
# calculate the reporting rate in each country using
# map on nested dataframes
df_reporting <- mutate(
df_reporting,
reporting = map(
.x = data, .f = estimate_ascertainment,
# arguments to function
severity_baseline = 0.014,
delay_density = delay_density
)
)
# unnest the data
df_reporting <- unnest(df_reporting, cols = "reporting")
# visualise the data
head(df_reporting)
```
```{r fig.cap = "Example plot of the ascertainment ratio by country during the early stages of the Covid-19 pandemic.", class.source = 'fold-hide'}
df_reporting %>%
ggplot() +
geom_pointrange(
aes(
x = fct_reorder(country, ascertainment_estimate),
y = ascertainment_estimate,
ymin = ascertainment_low,
ymax = ascertainment_high
)
) +
coord_flip() +
labs(x = NULL, y = "Ascertainment ratio") +
theme(legend.position = "none") +
scale_y_continuous(
labels = percent, limits = c(0, 1)
) +
theme_classic() +
theme(legend.position = "top")
```
## References