Skip to content

Commit 71679f6

Browse files
SMMR revision 1
- Updated the database to correspond to the corrected verion of The Lancet paper - Further tidied up some sections of the code - Added a "section 3" of the code for the validation
1 parent 408b6b0 commit 71679f6

32 files changed

Lines changed: 993 additions & 485 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,4 @@ rsconnect/
3838
# All data
3939
temp/
4040
old/
41+
figures/

00_DownloadData.R

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ library(data.table)
1212
library(readxl)
1313
library(zen4R)
1414
library(dplyr)
15+
library(tidyr)
1516
library(giscoR)
1617
library(sf)
1718

@@ -27,7 +28,7 @@ origagebreaks <- c(1, seq(5, 100, by = 5))
2728
# Target age groups (for the analysis)
2829
agebreaks <- c(0, 45, 65, 75, 85)
2930
agelabs <- c(paste(sprintf("%02i", agebreaks[-length(agebreaks)]),
30-
agebreaks[-1], sep = ""), sprintf("%i+", agebreaks[length(agebreaks)]))
31+
agebreaks[-1] - 1, sep = ""), sprintf("%i+", agebreaks[length(agebreaks)]))
3132

3233
#------------------------
3334
# Download mortality data
@@ -40,12 +41,15 @@ linkd <- paste0("https://www.istat.it/storage/dati_mortalita",
4041
"/decessi-comunali-giornalieri_4-21062023.zip")
4142

4243
# Download zip and open csv
43-
temp <- tempfile()
44+
temp <- tempfile(fileext = ".zip")
45+
tdir <- gsub("\\\\[[:alnum:]]*\\.zip", "", temp)
4446
download.file(linkd, temp)
4547
ftr <- grep("csv", zip_list(temp)$filename, value = T)
46-
deathdata <- fread(cmd = sprintf("unzip -p %s %s", temp, ftr),
48+
unzip(temp, ftr, exdir = tdir)
49+
deathdata <- fread(sprintf("%s\\%s", tdir, ftr),
4750
encoding = "Latin-1", na.string = "n.d.")
4851
unlink(temp)
52+
unlink(sprintf("%s\\%s", tdir, ftr))
4953

5054
# Pad province codes with zeros
5155
deathdata[, COD_PROVCOM := sprintf("%06d", COD_PROVCOM)]
@@ -80,13 +84,13 @@ years <- sprintf("20%s", substr(totalvars, 3, 4))
8084
# Reshape to long
8185
datalong <- melt.data.table(deathdata, id.vars = c("COD_PROVCOM", "REG",
8286
"PROV", "CL_ETA", "GE", "CITY_ID", "CITY_NAME"),
83-
measure.vars = totalvars, variable.name = "year", value.name = "all")
87+
measure.vars = totalvars, variable.name = "year", value.name = "deaths")
8488

8589
# Rename years
8690
datalong[, year := gsub("T_", "20", year, fixed = T)]
8791

8892
# Aggregate by city, date and age
89-
datatab <- datalong[, .(all = sum(all, na.rm = T)),
93+
datatab <- datalong[, .(deaths = sum(deaths, na.rm = T)),
9094
keyby = .(CITY_ID, year, GE, CL_ETA)]
9195

9296
# Create date variables
@@ -95,31 +99,33 @@ datatab[, day := GE - month * 100]
9599
datatab[, date := as.Date(paste(year, month, day, sep = "-"))]
96100

97101
# Create full list of dates
98-
fullfactor <- as.data.table(expand.grid(CITY_CODE = unique(datatab$CITY_ID),
102+
fullfactor <- as.data.table(expand.grid(city_code = unique(datatab$CITY_ID),
99103
date = seq(dstart, dend, by = "day"), agegroup = 0:21))
100104

101105
# Merge with datatab
102106
fulldata <- merge(fullfactor, datatab,
103-
by.x = c("CITY_CODE", "date", "agegroup"),
107+
by.x = c("city_code", "date", "agegroup"),
104108
by.y = c("CITY_ID", "date", "CL_ETA"), all.x = T, all.y = F)
105109

106110
# Fill NAs
107-
fulldata[, all := nafill(all, fill = 0)]
111+
fulldata[, deaths := nafill(deaths, fill = 0)]
108112

109113
# Clean date related variables
110114
fulldata[, ":="(year = NULL, month = NULL, day = NULL, GE = NULL)]
111115

112116
# Aggregate age-groups
113117
fulldata[, agegroup := cut(c(0, origagebreaks)[agegroup + 1], c(agebreaks, Inf),
114118
right = F, labels = agelabs)]
115-
fulldata <- fulldata[, .(all = sum(all)), by = .(CITY_CODE, date, agegroup)]
119+
fulldata <- fulldata[, .(deaths = sum(deaths)),
120+
by = .(city_code, date, agegroup)]
116121

117122
# Transform age groups as wide
118-
fulldata <- dcast.data.table(fulldata, CITY_CODE + date ~ agegroup,
119-
value.var = "all")
123+
fulldata <- dcast.data.table(fulldata, city_code + date ~ agegroup,
124+
value.var = "deaths")
125+
setnames(fulldata, agelabs, sprintf("deaths_%s", agelabs))
120126

121-
# Rename
122-
setnames(fulldata, agelabs, sprintf("all_%s", agelabs))
127+
# Arrange
128+
setorder(fulldata, city_code, date)
123129

124130
#----- Save
125131

@@ -137,18 +143,21 @@ if (!file.exists(fname)){
137143

138144
#----- Metadata
139145

140-
# Download metadata used in The Lancet Planetary Health paper from Zenodo
141-
download_zenodo("10.5281/zenodo.7672108", path = "data",
146+
# Download data used in The Lancet Planetary Health paper from Zenodo
147+
# Also include the metadata
148+
# download_zenodo("10.5281/zenodo.7672108", path = tdir,
149+
# files = list("metadata.csv"))
150+
download_zenodo("10.5281/zenodo.10288665", path = tdir,
142151
files = list("metadata.csv"))
143152

144153
# Read metadata
145-
metadata <- read.csv("data/metadata.csv")
146-
unlink("data/metadata.csv")
154+
metadata <- read.csv(sprintf("%s/metadata.csv", tdir))
155+
unlink(sprintf("%s/metadata.csv", tdir))
147156

148157
# Select only Italy
149158
metadata <- subset(metadata, CNTR_CODE == "IT", -c(CNTR_CODE, cntr_name, region,
150-
nmiss, mcc_code, cityname, country, inmcc)) |>
151-
rename(CITY_CODE = "URAU_CODE", CITY_NAME = "URAU_NAME")
159+
nmiss, mcc_code, cityname, country, inmcc, LABEL)) |>
160+
rename(city_code = "URAU_CODE", city_name = "URAU_NAME")
152161

153162
#----- Info about municipalities
154163

@@ -157,12 +166,15 @@ linkg <- paste0("https://www.istat.it/storage/codici-unita-amministrative",
157166
"/Elenco-codici-statistici-e-denominazioni-delle-unita-territoriali.zip")
158167

159168
# Download and load into session
160-
temp <- tempfile()
169+
temp <- tempfile(fileext = ".zip")
170+
tdir <- gsub("\\\\[[:alnum:]]*\\.zip", "", temp)
161171
download.file(linkg, temp)
162-
ftr <- grep("csv", zip_list(temp)$filename, value = T)
163-
geoinfo <- fread(cmd = sprintf("unzip -p %s %s", temp, ftr),
172+
ftr <- grep("csv", zip_list(temp)$filename, value = T, useBytes = T)
173+
unzip(temp, ftr, exdir = tdir, junkpaths = T)
174+
geoinfo <- fread(sprintf("%s\\%s", tdir, gsub("^.*/", "", ftr, useBytes = T)),
164175
encoding = "Latin-1", na.string = "n.d.")
165176
unlink(temp)
177+
unlink(sprintf("%s\\%s", tdir, gsub("^.*/", "", ftr, useBytes = T)))
166178

167179
# Link to cities, select and rename
168180
geoinfo <- mutate(geoinfo, `LAU CODE` = sprintf("%06d",
@@ -173,12 +185,29 @@ geoinfo <- mutate(geoinfo, `LAU CODE` = sprintf("%06d",
173185
unique()
174186

175187
# Add to metadata
176-
metadata <- merge(metadata, geoinfo, by.x = "CITY_CODE", by.y = "CITY_ID")
188+
metadata <- merge(metadata, geoinfo, by.x = "city_code", by.y = "CITY_ID")
189+
190+
# Separate spatial and age-related variables
191+
agevars <- grep("[[:alpha:]]+_[[:digit:]]+$", names(metadata), value = T)
192+
metadata_spatial <- metadata[, !names(metadata) %in% agevars]
193+
194+
# Age-related variables into long and characterise age groups
195+
metadata_age <- metadata[, c("city_code", agevars)]
196+
names(metadata_age) <- gsub("([^_])[[:digit:]]{2}$", "\\1", names(metadata_age))
197+
metadata_age <- pivot_longer(metadata_age, cols = !city_code,
198+
names_to = c(".value", "age"), names_sep = "_") |>
199+
arrange(city_code, age) |>
200+
mutate(age = as.numeric(age), agehigh = lead(age) - 1, .by = city_code) |>
201+
select(city_code, age, agehigh, prop, deathrate, lifexp)
202+
177203

178204
# Write metadata
179-
fname <- "data/metadata.csv.gz"
205+
fname <- "data/metadata_spatial.csv.gz"
180206
if (!file.exists(fname)){
181-
fwrite(metadata, fname, quote = F, compress = "gzip")
207+
fwrite(metadata_spatial, "data/metadata_spatial.csv.gz",
208+
quote = F, compress = "gzip")
209+
fwrite(metadata_age, "data/metadata_age.csv.gz",
210+
quote = F, compress = "gzip")
182211
}
183212

184213
#----- Geographical data

11_Packages.R

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,4 @@ library(ggdist)
4141
library(fields)
4242
library(tidyterra)
4343
library(ggnewscale) # To have several fill scales on the same plot
44+
library(ggforce) # For facet paginate

12_Parameters.R

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ lagknots <- logknots(maxlag, 3)
2929

3030
# List of metapredictors in composite indices
3131
metaprednames <- c(Population = "pop", 'Population above 65' = "prop_65p",
32-
'Population density' = "popdens", 'Life expectancy' = "lifexp_00",
32+
'Population density' = "popdens",
3333
'Social isolation' = "isol", GPD = "gdp", 'Unemployment rate' = "unempl",
3434
'Educational level' = "educ", 'Deprivation rate' = "depriv",
3535
'Hospital bed rate' = "bedrates", Imperviousness = "imperv",
@@ -40,15 +40,15 @@ metaprednames <- c(Population = "pop", 'Population above 65' = "prop_65p",
4040
'Temperature range' = "trange")
4141

4242
# Number of composite vulnerability indices
43-
npc <- 5
43+
npc <- 6
4444

4545
# Number of simulations for eCI
4646
nsim <- 1000
4747

4848
#----- Results
4949

5050
# Temperature percentile grid for ERFs
51-
predper <- c(seq(0.1,1,0.1), 2:98, seq(99,99.9,0.1))
51+
predper <- c(seq(0,1,0.1), 2:98, seq(99,100,0.1))
5252

5353
# Acceptable MMP range
5454
mmprange <- c(25, 99)
@@ -58,3 +58,6 @@ axisper <- c(1, 25, 50, 75, 99)
5858

5959
# Denominator for death rates
6060
byrate <- 10^5
61+
62+
# Ages to which to display results
63+
agebreaks <- c(45, 65, 75, 85)

13_PrepData.R

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -15,44 +15,46 @@ mortdata <- fread("data/mortality.csv.gz")
1515

1616
# Read temperature series and merge
1717
tempdata <- fread("data/tmean.csv.gz")
18-
fulldata <- merge(mortdata, tempdata, by.x = c("CITY_CODE", "date"),
19-
by.y = c("URAU_CODE", "date"))
18+
tsdata <- merge(mortdata, tempdata, all.x = T)
2019

2120
# Order
22-
setkey(fulldata, CITY_CODE, date)
21+
setkey(tsdata, city_code, date)
2322

2423
# Create date-related variables
25-
fulldata[, ":="(year = year(date), dow = weekdays(date))]
26-
27-
# Split
28-
dlist <- split(fulldata[,!"CITY_CODE"], fulldata$CITY_CODE)
29-
dlist <- lapply(dlist, as.data.frame)
24+
tsdata[, ":="(year = year(date), dow = weekdays(date))]
3025

3126
#---------------------------
3227
# Read Metadata
3328
#---------------------------
3429

35-
# Load data from EUcityTRM
36-
metadata <- read.csv("data/metadata.csv.gz")
30+
# Create all city-age combinations
31+
agelabs <- grep("deaths_[[:digit:]]", names(tsdata), value = T) |>
32+
gsub(pattern = "deaths_", replacement = "")
33+
metadf <- expand.grid(agegroup = agelabs,
34+
city_code = unique(tsdata$city_code))
35+
36+
# Load data from EUcityTRM and merge
37+
metadata_spatial <- read.csv("data/metadata_spatial.csv.gz")
38+
metadf <- merge(metadf, metadata_spatial)
39+
40+
# Load age-specific demographic data
41+
metadata_age <- read.csv("data/metadata_age.csv.gz")
42+
43+
44+
#---------------------------
45+
# Separate observed and predicted cities
46+
#---------------------------
3747

3848
# Draw observed cities for the first stage
3949
set.seed(1)
40-
obs <- sample.int(nrow(metadata), nobs)
41-
metadata$obs <- seq_len(nrow(metadata)) %in% obs
42-
43-
# Create all city-age combinations
44-
agelabs <- grep("all_[[:digit:]]", names(fulldata), value = T) |>
45-
gsub(pattern = "all_", replacement = "")
46-
stage2df <- expand.grid(agegroup = agelabs, city = metadata$CITY_CODE)
50+
obs <- sample(unique(tsdata$city_code), nobs)
4751

48-
# Add name, and geographical information
49-
stage2df <- merge(stage2df,
50-
metadata[, c("CITY_CODE" ,"CITY_NAME", "geozone", "lon", "lat", "obs")],
51-
by.x = "city", by.y = "CITY_CODE")
52+
# Separate time series data
53+
tspred <- tsdata[!city_code %in% obs]
54+
tsdata <- tsdata[city_code %in% obs]
5255

53-
# Separate data.frame
54-
stage2_obs <- subset(stage2df, obs)
55-
stage2_pred <- subset(stage2df, !obs)
56+
# Include info in metadata
57+
metadf <- mutate(metadf, obs = city_code %in% obs)
5658

5759
#---------------------------
5860
# Additional data for results
@@ -64,12 +66,12 @@ italymap <- st_read("data/italymap.shp")
6466
#----- Common basis to represent curves
6567

6668
# Estimate an overall empirical distribution of temperature
67-
tmeandist <- t(sapply(dlist,
68-
function(x) quantile(x$tmean, predper / 100, na.rm = T)))
69-
ovper <- colMeans(tmeandist)
69+
tmeandist <- tempdata[, .(per = predper, tper = quantile(tmean, predper / 100)),
70+
by = city_code]
71+
ovper <- tmeandist[, .(tmean = mean(tper)), by = per]$tmean
7072

7173
# Create average basis
72-
ovknots <- ovper[sprintf("%i.0%%",varper)]
74+
ovknots <- ovper[predper %in% varper]
7375
ovbasis <- onebasis(ovper, fun = varfun, degree = vardegree, knots = ovknots)
7476

7577
# Axis locations for plots
@@ -82,13 +84,11 @@ mmtper <- ovper[between(predper, mmprange[1], mmprange[2])]
8284
#----- Useful objects
8385

8486
# Number of spline coefficients
85-
nc <- length(varper) + 2
87+
nc <- ncol(ovbasis)
8688

8789
# Number of cities
88-
n <- nrow(metadata)
90+
n <- nrow(metadata_spatial)
8991

9092
# Number of city-ages
91-
na <- nrow(stage2df)
93+
na <- nrow(metadf)
9294

93-
# Length of time series
94-
nts <- nrow(dlist[[1]])

0 commit comments

Comments
 (0)