COVID-19 Number of Tests in Italy

Table of Contents

Menu

Introduction

This page presents some data about the number of tests and people tested for COVID-19 over time in Italy and compares them with the number of people found positive.

This page was created on <2020-08-20 Thu> and last updated on <2020-10-29 Thu>.

The source code available on the COVID-19 pages is distributed under the MIT License; the content is distributed under a Creative Commons - Attribution 4.0.

Getting data into R

We first read the data from the Civil Protection repository adding the ratio between positives and tests, computed on the same day and computed with data shifted by two days (on the assumption tests take two days to complete).

In fact data about tests is used with different semantics by different regions. Some regions reports tests with results (and the ratio new positives / tests makes sense). Other reports the number of test performed, in which case the correct ratio is between positives and tests performed some days earlier. We assume two days and report both ratios for all regions. See the following issue on GitHub for an explanation and some more details https://github.com/pcm-dpc/COVID-19/issues/577 (in Italian).

PATH="/home/adolfo/Downloads/COVID-19/"
DIGITS = 4

national = read.csv(file.path(PATH, "dati-andamento-nazionale/dpc-covid19-ita-andamento-nazionale.csv"))
national$data <- as.Date(national$data)
national$nuovi_casi_testati = c(NA, diff(national$casi_testati, 1))
national$p_over_t <- round(national$nuovi_positivi / national$nuovi_casi_testati, digits = DIGITS) * 100
national$nuovi_casi_testati_2 <- c(NA, NA, head(national$nuovi_casi_testati, -2))
national$p_over_t_2 = round(national$nuovi_positivi / national$nuovi_casi_testati_2, digits = DIGITS) * 100

Concerning the regional level, computed columns, such as the number of people tested in a day, have to be computed after filtering, or the diif will work on values from different regions.

# evolution over time, by Region
data = read.csv(file.path(PATH, "dati-regioni/dpc-covid19-ita-regioni.csv"))
data$data <- as.Date(data$data)

These are the columns we are interested in and their translation in English:

cols = c(
  "data",
  "casi_testati",
  "totale_positivi",
  "nuovi_casi_testati",
  "nuovi_positivi",
  "p_over_t",
  "p_over_t_2"
)

We now define a function to ouput the last N rows of the input data frame. The real “challenge”, here, is transposing the data, to get a more natural presentation (with time progressing from left to right).

table_data <- function(df, cols, rows = 10) {
  # get the last 10 elements and the interesting columns of the dataframe
  f  <- tail(df, rows)
  rf <- f[, cols]

  # the labels in the transposed matrix are the column names of the original data.frame
  row_labels  <- colnames(rf)
  # the columns in the trasposed matrix are the dates
  col_labels  <- c("Label", format(rf$data, "%a, %b %d"))

  rft <- data.frame(row_labels, t(rf))
  colnames(rft) <- col_labels
  return(rft[-1,])
}

People Tested and Cases in Italy

Data of the last ten days

table_data(national, cols)
Label Tue, Nov 24 Wed, Nov 25 Thu, Nov 26 Fri, Nov 27 Sat, Nov 28 Sun, Nov 29 Mon, Nov 30 Tue, Dec 01 Wed, Dec 02 Thu, Dec 03
casi_testati 12398952 12513129 12623390 12729411 12842250 12922382 12986634 13071746 13167345 23333937
totale_positivi 798386 791697 795845 787893 789308 795771 788471 779945 761230 759982
nuovi_casi_testati 95247 114177 110261 106021 112839 80132 64252 85112 95599 10166592
nuovi_positivi 23232 25853 29003 28352 26323 20648 16377 19350 20709 23225
p_over_t 24.39 22.64 26.3 26.74 23.33 25.77 25.49 22.73 21.66 0.23
p_over_t_2 22.16 33.21 30.45 24.83 23.87 19.48 14.51 24.15 32.23 27.29

New Cases

New cases.

## add extra space to right margin of plot within frame
par(mar=c(5, 4, 4, 6) + 0.1)

## Allow a second plot on the same graph
# par(new=TRUE)
new_cases_limits = c( min(national[national$data >= "2020-08-01", c("nuovi_positivi")]), max(national[national$data >= "2020-08-01", c("nuovi_positivi")]) )

p = plot(x = national[national$data >= "2020-08-01", c("data")], 
     y = national[national$data >= "2020-08-01", c("nuovi_positivi")], 
     type="l", lwd=6, pch=21, cex=1.5, col=c("#AA0000"),
     axes=FALSE,
     ylim=new_cases_limits,
     ylab="", xlab="")
text(x = national[national$data >= "2020-08-01", c("data")],
     y = national[national$data >= "2020-08-01", c("nuovi_positivi")],
     labels = national[national$data >= "2020-08-01", c("nuovi_positivi")],
     pos = 1, cex = 1, col="#AA0000")
mtext("New Cases", side=4, line=4, col="#AA0000") 
axis(4, ylim=new_cases_limits, las=1)

grid(p, col = "black", lty = "dotted")

# x-axis
dates = national[national$data >= "2020-08-01", c("data")]
axis.Date(1, at=seq(min(dates), max(dates), by="week"), format="%b %d", las=2)
mtext("Day", side=1, line=2.5)

## Add Legend
legend("topleft", legend = c("Tests", "New Cases"),
       text.col = c("#3B3176", "#AA0000"), pch= c(15, 17), col=c("#3B3176", "#AA0000"))

new_cases_italia.png

New Cases Tested

plot(x = national[national$data >= "2020-08-01", c("data")], 
     y = national[national$data >= "2020-08-01", c("nuovi_casi_testati")], 
     type="l", lwd=6, pch=16, cex=2.5, col=c("#3B3176"))
text(x = national[national$data >= "2020-08-01", c("data")],
     y = national[national$data >= "2020-08-01", c("nuovi_casi_testati")],
     labels = national[national$data >= "2020-08-01", c("nuovi_casi_testati")],
     pos = 3, cex = 1.5, col=c("#3B3176"))
 grid(col="black")

tests_italia.png

Number of Tests and New Cases Tested

Plot new cases and tests together. (Solution taken from How can I plot with 2 different y-axes? on Stack Overflow.)

## add extra space to right margin of plot within frame
par(mar=c(5, 4, 4, 6) + 0.1)

## Plot first set of data and draw its axis
tests_limits = c( min(national[national$data >= "2020-08-01", c("nuovi_casi_testati")]), max(national[national$data >= "2020-08-01", c("nuovi_casi_testati")]) )
plot(x = national[national$data >= "2020-08-01", c("data")], 
     y = national[national$data >= "2020-08-01", c("nuovi_casi_testati")], 
     type="l", lwd=6, pch=11, cex=1.5, col=c("#3B3176"),
     axes=FALSE,
     ylim=tests_limits,
     ylab="", xlab="")
text(x = national[national$data >= "2020-08-01", c("data")],
     y = national[national$data >= "2020-08-01", c("nuovi_casi_testati")],
     labels = national[national$data >= "2020-08-01", c("nuovi_casi_testati")],
     pos = 3, cex = 1, col=c("#3B3176"))
mtext("Number of Tests", side=2, col="#3B3176", line=4) 
axis(2, ylim=tests_limits, col="black", las=1)  
box()

## Allow a second plot on the same graph
par(new=TRUE)
new_cases_limits = c( min(national[national$data >= "2020-08-01", c("nuovi_positivi")]), max(national[national$data >= "2020-08-01", c("nuovi_positivi")]) )

p = plot(x = national[national$data >= "2020-08-01", c("data")], 
     y = national[national$data >= "2020-08-01", c("nuovi_positivi")], 
     type="l", lwd=6, pch=21, cex=1.5, col=c("#AA0000"),
     axes=FALSE,
     ylim=new_cases_limits,
     ylab="", xlab="")
text(x = national[national$data >= "2020-08-01", c("data")],
     y = national[national$data >= "2020-08-01", c("nuovi_positivi")],
     labels = national[national$data >= "2020-08-01", c("nuovi_positivi")],
     pos = 1, cex = 1, col="#AA0000")
mtext("New Cases", side=4, line=4, col="#AA0000") 
axis(4, ylim=new_cases_limits, las=1)

grid(p, col = "black", lty = "dotted")

# x-axis
dates = national[national$data >= "2020-08-01", c("data")]
axis.Date(1, at=seq(min(dates), max(dates), by="week"), format="%b %d", las=2)
mtext("Day", side=1, line=2.5)

## Add Legend
legend("topleft", legend = c("Tests", "New Cases"),
       text.col = c("#3B3176", "#AA0000"), pch= c(15, 17), col=c("#3B3176", "#AA0000"))

tests_and_new_cases_italia.png

Positive/Number of Tests

plot(national$p_over_t ~ national$data, type="o", lwd=2, col="#FF0000", main="Positive over New People Tested", xlab="Date", ylab="Percentage")
text(y = tail(national, 1)$p_over_t, x = tail(national, 1)$data, lab = tail(national, 1)$p_over_t, pos=3, col="#ff0000", cex=1.3)
grid(col="black")

positive_over_tests_italia.png

People Tested and Cases in Trentino

region <- subset(data, denominazione_regione == "P.A. Trento")

region$nuovi_casi_testati = c(NA, diff(region$casi_testati, 1))
region$p_over_t <- round(region$nuovi_positivi / region$nuovi_casi_testati, digits = DIGITS) * 100
region$nuovi_casi_testati_2 = c(NA, NA, diff(region$casi_testati, 2))
region$p_over_t_2 = round(region$nuovi_positivi / region$nuovi_casi_testati_2, digits = DIGITS) * 100
region$nuovi_casi_testati_2 <- c(NA, NA, head(region$nuovi_casi_testati, -2))
region$p_over_t_2 = round(region$nuovi_positivi / region$nuovi_casi_testati_2, digits = DIGITS) * 100

table_data(region, cols)
Label Tue, Nov 24 Wed, Nov 25 Thu, Nov 26 Fri, Nov 27 Sat, Nov 28 Sun, Nov 29 Mon, Nov 30 Tue, Dec 01 Wed, Dec 02 Thu, Dec 03
casi_testati 129600 130165 131463 132813 134489 135008 135274 136084 137151 138153
totale_positivi 2472 2447 2362 2309 2133 2319 2448 2450 2459 2532
nuovi_casi_testati 827 565 1298 1350 1676 519 266 810 1067 1002
nuovi_positivi 143 179 297 229 219 265 176 156 278 239
p_over_t 17.29 31.68 22.88 16.96 13.07 51.06 66.17 19.26 26.05 23.85
p_over_t_2 15.84 34.23 35.91 40.53 16.87 19.63 10.5 30.06 104.51 29.51

People Tested and Cases in Liguria

region <- subset(data, denominazione_regione == "Liguria")

region$nuovi_casi_testati = c(NA, diff(region$casi_testati, 1))
region$p_over_t <- round(region$nuovi_positivi / region$nuovi_casi_testati, digits = DIGITS) * 100
region$nuovi_casi_testati_2 = c(NA, NA, diff(region$casi_testati, 2))
region$p_over_t_2 = round(region$nuovi_positivi / region$nuovi_casi_testati_2, digits = DIGITS) * 100
region$nuovi_casi_testati_2 <- c(NA, NA, head(region$nuovi_casi_testati, -2))
region$p_over_t_2 = round(region$nuovi_positivi / region$nuovi_casi_testati_2, digits = DIGITS) * 100

table_data(region, cols)
Label Tue, Nov 24 Wed, Nov 25 Thu, Nov 26 Fri, Nov 27 Sat, Nov 28 Sun, Nov 29 Mon, Nov 30 Tue, Dec 01 Wed, Dec 02 Thu, Dec 03
casi_testati 281926 283560 285519 287369 288865 290019 290739 292065 293385 294667
totale_positivi 14783 14055 13492 13011 12725 12606 12216 12150 11999 11458
nuovi_casi_testati 1752 1634 1959 1850 1496 1154 720 1326 1320 1282
nuovi_positivi 509 460 570 606 454 437 236 339 349 422
p_over_t 29.05 28.15 29.1 32.76 30.35 37.87 32.78 25.57 26.44 32.92
p_over_t_2 32.4 48.47 32.53 37.09 23.18 23.62 15.78 29.38 48.47 31.83

People Tested and Cases in Veneto

region <- subset(data, denominazione_regione == "Veneto")

region$nuovi_casi_testati = c(NA, diff(region$casi_testati, 1))
region$p_over_t <- round(region$nuovi_positivi / region$nuovi_casi_testati, digits = DIGITS) * 100
region$nuovi_casi_testati_2 = c(NA, NA, diff(region$casi_testati, 2))
region$p_over_t_2 = round(region$nuovi_positivi / region$nuovi_casi_testati_2, digits = DIGITS) * 100
region$nuovi_casi_testati_2 <- c(NA, NA, head(region$nuovi_casi_testati, -2))
region$p_over_t_2 = round(region$nuovi_positivi / region$nuovi_casi_testati_2, digits = DIGITS) * 100

table_data(region, cols)
Label Tue, Nov 24 Wed, Nov 25 Thu, Nov 26 Fri, Nov 27 Sat, Nov 28 Sun, Nov 29 Mon, Nov 30 Tue, Dec 01 Wed, Dec 02 Thu, Dec 03
casi_testati 1035198 1039770 1045655 1050631 1055933 1059827 1062810 1066796 1070844 1077351
totale_positivi 73354 75138 75152 76888 78572 79711 80665 80997 68792 70603
nuovi_casi_testati 4224 4572 5885 4976 5302 3894 2983 3986 4048 6507
nuovi_positivi 2194 2660 3980 3418 3498 2617 2003 2535 2782 3581
p_over_t 51.94 58.18 67.63 68.69 65.98 67.21 67.15 63.6 68.73 55.03
p_over_t_2 44.97 72.82 94.22 74.76 59.44 52.59 37.78 65.1 93.26 89.84

People Tested and Cases in Lombardia

region <- subset(data, denominazione_regione == "Lombardia")

region$nuovi_casi_testati = c(NA, diff(region$casi_testati, 1))
region$p_over_t <- round(region$nuovi_positivi / region$nuovi_casi_testati, digits = DIGITS) * 100
region$nuovi_casi_testati_2 = c(NA, NA, diff(region$casi_testati, 2))
region$p_over_t_2 = round(region$nuovi_positivi / region$nuovi_casi_testati_2, digits = DIGITS) * 100
region$nuovi_casi_testati_2 <- c(NA, NA, head(region$nuovi_casi_testati, -2))
region$p_over_t_2 = round(region$nuovi_positivi / region$nuovi_casi_testati_2, digits = DIGITS) * 100

table_data(region, cols)
Label Tue, Nov 24 Wed, Nov 25 Thu, Nov 26 Fri, Nov 27 Sat, Nov 28 Sun, Nov 29 Mon, Nov 30 Tue, Dec 01 Wed, Dec 02 Thu, Dec 03
casi_testati 2274365 2289221 2304509 2319630 2333345 2343093 2349286 2361598 2372367 2383936
totale_positivi 148760 138029 140401 130555 130315 132627 125408 121033 118796 118331
nuovi_casi_testati 11380 14856 15288 15121 13715 9748 6193 12312 10769 11569
nuovi_positivi 4886 5173 5697 5389 4615 3203 1929 4048 3425 3751
p_over_t 42.93 34.82 37.26 35.64 33.65 32.86 31.15 32.88 31.8 32.42
p_over_t_2 40.32 36.5 50.06 36.27 30.19 21.18 14.06 41.53 55.3 30.47

Author: Adolfo Villafiorita

Last modified: 2020-10-29 Thu 18:06 (created on: 2020-08-20 Thu 00:00)

Published: 2020-12-04 Fri 13:20