targets
pipelineHere’s the general process for building and running this analysis. This is all done with the magical targets
package, which orchestrates all the dependencies automatically.
All the data processing is handled with dataset-specific functions that live in R/funs_data-cleaning.R
, which targets
then runs as needed. For the sake of transparency, here’s that code:
<- function() {
create_lookups <- tribble(
emlaw_lookup ~emlaw, ~emlaw_fct, ~emlaw_cond,
1, "Declaration in existing legal framework", "Emergency response with legal instruments",
2, "Declaration in existing legal framework, distinguishes public health emergency", "Emergency response with legal instruments",
3, "Declaration of disaster where different from emergency", "Emergency response with legal instruments",
4, "Declaration using other legislation", "Emergency response with legal instruments",
5, "Emergency response without legal instruments", "Emergency response without legal instruments",
6, "No emergency response", "No emergency response",
7, "Other", "Other"
)
<- tribble(
regime_lookup ~v2x_regime, ~regime,
0, "Closed autocracy",
1, "Electoral autocracy",
2, "Electoral democracy",
3, "Liberal democracy"
%>%
) mutate(regime = fct_inorder(regime, ordered = TRUE))
<- tribble(
type_lookup ~type, ~type_clean,
"A", "Derogated as intended",
"B", "Derogated; measures not temporary, proportional, or necessary",
"C", "Emergency declared; no formal derogation",
"D", "No emergency; no formal derogation",
"E", "Has not ratified ICCPR"
%>%
) mutate(type_clean_letter = paste0(type, ": ", type_clean)) %>%
mutate(across(starts_with("type"), ~fct_inorder(., ordered = TRUE)))
<- tribble(
civicus_lookup ~value, ~category,
1, "Closed",
2, "Repressed",
3, "Obstructed",
4, "Narrowed",
5, "Open"
%>%
) mutate(category = fct_inorder(category, ordered = TRUE))
return(list(emlaw = emlaw_lookup,
regime = regime_lookup,
type = type_lookup,
civicus = civicus_lookup))
}
<- function(path, lookup) {
load_clean_pandem <- read_csv(path, col_types = cols()) %>% suppressWarnings()
pandem_raw
<- pandem_raw %>%
pandem_clean mutate(ndrights_fct = factor(ndrights, levels = 0:1,
labels = c("No violations", "Violations of non-derogable rights"))) %>%
group_by(country_name) %>%
mutate(emlaw_min = min(emlaw),
pandem_max = max(pandem),
panback_max = max(panback)) %>%
ungroup() %>%
left_join(lookup$emlaw, by = "emlaw") %>%
left_join(rename_with(lookup$emlaw, ~str_c(., "_min"), everything()), by = "emlaw_min") %>%
left_join(lookup$regime, by = "v2x_regime") %>%
mutate(emlaw_fct = factor(emlaw_fct, levels = lookup$emlaw$emlaw_fct, ordered = TRUE),
emlaw_cond = factor(emlaw_cond, levels = unique(lookup$emlaw$emlaw_cond), ordered = TRUE)) %>%
mutate(emlaw_min_fct = factor(emlaw_fct, levels = lookup$emlaw$emlaw_fct, ordered = TRUE),
emlaw_min_cond = factor(emlaw_cond, levels = unique(lookup$emlaw$emlaw_cond), ordered = TRUE)) %>%
mutate(cowcode = countrycode(country_name, "country.name", "cown",
custom_match = c("Serbia" = 345,
"Hong Kong" = 997)),
iso3 = countrycode(country_name, "country.name", "iso3c"))
return(pandem_clean)
}
<- function(pandem) {
create_pandem_single %>%
pandem filter(Quarter == "Q4")
}
<- function(path) {
load_clean_derogations <- read_csv(path, col_types = cols())
derogations_raw
<- derogations_raw %>%
derogations_clean rename(ratified = `Did they ratify/are they a member? (1=Yes, 0=No, 99= Not possible)`,
derogate = `Did they officially derogate?`,
derogation_start = `Derogation start date`,
derogation_end = `Derogation end date`,
country_name = Country) %>%
mutate(country_name = recode(country_name, "Columbia" = "Colombia")) %>%
mutate(cowcode = countrycode(country_name, "country.name", "cown",
custom_match = c("Serbia" = 345,
"State of Palestine" = 998,
"Cook Islands" = NA,
"Niue" = NA)),
iso3 = countrycode(country_name, "country.name", "iso3c"))
return(derogations_clean)
}
<- function(path) {
load_clean_vdem <- read_rds(path) %>% as_tibble()
vdem_raw
<- vdem_raw %>%
vdem_clean filter(year > 2015) %>%
rename(cowcode = COWcode) %>%
mutate(cowcode = case_when(
== "Hong Kong" ~ 997,
country_name == "Palestine/West Bank" ~ 998,
country_name TRUE ~ cowcode
%>%
)) mutate(iso3c = countrycode(country_name, "country.name", "iso3c",
custom_match = c("Kosovo" = "XKK",
"Somaliland" = "XSO",
"Zanzibar" = "EAZ"))) %>%
select(country_name, year, cowcode, iso3c,
# Civil society stuff
# CSO entry and exit
v2cseeorgs, # CSO repression
v2csreprss, # CSO consultation
v2cscnsult, # CSO participatory environment
v2csprtcpt, # CSO women's participation
v2csgender, # CSO anti-system movements
v2csantimv, # Core civil society index (entry/exit, repression, participatory env)
v2xcs_ccsi, # Human rights and politics
# Political corruption index (less to more, 0-1) (public sector +
# executive + legislative + judicial corruption)
v2x_corr,# Rule of law index
v2x_rule,# Rights indexes
# Civil liberties index
v2x_civlib, # Physical violence index
v2x_clphy, # Private civil liberties index
v2x_clpriv, # Political civil liberties index
v2x_clpol, # Democracy
v2x_polyarchy
)
return(vdem_clean)
}
# Civicus Monitor
# We downloaded the standalone embeddable widget
# (https://monitor.civicus.org/widgets/world/) as an HTML file with
# `wget https://monitor.civicus.org/widgets/world/` and saved it as index_2021-03-19.html
#
# We then extracted the COUNTRIES_DATA variable embedded in a <script> tag
# (xpath = /html/body/script[5]), which is JSON-ish, but not quite. jsonlite
# can't parse it for whatever reason, but some online JSON formatter and
# validator could, so we ran it through that and saved the resulting clean file
<- function(path, lookup) {
load_clean_civicus <- read_json(path) %>% as_tibble() %>% slice(1)
civicus_raw
<- civicus_raw %>%
civicus_clean pivot_longer(everything(), names_to = "name", values_to = "value") %>%
mutate(value = map_chr(value, ~.)) %>%
mutate(value = parse_number(value, na = c("", "NA", "None"))) %>%
mutate(country_name = countrycode(name, "iso3c", "country.name",
custom_match = c("KOSOVO" = "XKK",
"SVT" = "VCT")),
iso3c = countrycode(country_name, "country.name", "iso3c",
custom_match = c("XKK" = "Kosovo",
"VCT" = "Saint Vincent and the Grenadines"))) %>%
left_join(lookup$civicus, by = "value") %>%
select(-name, -value, -country_name)
return(civicus_clean)
}
<- function(derogations, pandem, vdem, lookups) {
create_pandem_derog <- derogations %>%
pandem_derog left_join(pandem, by = c("country_name", "cowcode", "iso3")) %>%
left_join(filter(vdem, year == 2019), by = c("country_name", "cowcode")) %>%
filter(!is.na(X1)) %>%
mutate(has_derogation_end = case_when(
is.na(derogation_end) ~ FALSE,
str_detect(derogation_end, "N/A") ~ FALSE,
TRUE ~ TRUE
%>%
)) mutate(has_emergency_end = emlimit == 1) %>%
mutate(nonproportional = Type1 > 1 | Type2 == 1 | Type3 > 1) %>%
mutate(type = case_when(
== 1 & has_derogation_end & !nonproportional ~ "A",
derogate == 1 & (!has_derogation_end | nonproportional) ~ "B",
derogate == 0 & ratified == 1 & emlaw < 5 ~ "C",
derogate == 0 & ratified == 1 & emlaw >= 5 ~ "D",
derogate TRUE ~ "E"
%>%
)) left_join(lookups$type, by = "type")
return(pandem_derog)
}
<- function(path) {
load_world_map <- read_sf(path) %>%
world_map filter(ISO_A3 != "ATA")
return(world_map)
}
<- function(civicus, map) {
create_civicus_map_data <- map %>%
map_with_civicus # Fix some Natural Earth ISO weirdness
mutate(ISO_A3 = ifelse(ISO_A3 == "-99", as.character(ISO_A3_EH), as.character(ISO_A3))) %>%
mutate(ISO_A3 = case_when(
$ISO_A3 == "GRL" ~ "DNK",
.$NAME == "Norway" ~ "NOR",
.$NAME == "Kosovo" ~ "XKK",
.TRUE ~ ISO_A3
%>%
)) left_join(civicus, by = c("ISO_A3" = "iso3c"))
return(map_with_civicus)
}