A Clustering Approach
This article explores how the unequal and paradoxical distribution of the benefits of hyper-globalization has fostered its own crisis. By analyzing the national trajectories of Global North and Global South countries within Global Value Chains (GVCs), we use K-means clustering to identify distinct patterns of international trade and economic growth over time. While some countries, mainly from the Global South, have successfully used GVCs for growth, others, mainly from the Global North, have experienced stagnation or decline. These differences highlight the complexity of the effects of hyper-globalization and explain the need to promote transformations for those countries that have not fully benefited from this system. These findings have important implications for understanding the economic and political dynamics of the new global order.
knitr::opts_chunk$set(echo = TRUE)
#install.packages(c("tidyverse","readxl", "wbstats","rempsyc", "ggrepel","ggtext", "scales","gghighlight","factoextra", "cluster"))
library(tidyverse)
library(readxl)
library(wbstats)
library(rempsyc)
library(ggrepel)
library(ggtext)
library(scales)
library(gghighlight)
library(factoextra)
library(cluster)
library(gridExtra)
options(scipen=999)
url <- "https://www.worldmrio.com/unctadgvc/Database_GVC_2018update_rev0323.csv"
GVC_base <- read.csv(url)
divide_columnas <- function(x, y) {
return(x / y)
}
GVC<- GVC_base %>%
mutate(across(starts_with("GVC"),
~ divide_columnas(.x, get(paste0("VA_exp", gsub("\\D", "", cur_column())))),
.names = "{.col}_percent")) %>%
select("X" ,"GVC1990_percent","GVC1995_percent","GVC2000_percent","GVC2008_percent","GVC2018_percent") %>%
pivot_longer(names_to = "Year", cols = contains("_")) %>%
mutate(Year = str_replace(Year, "_percent", "")) %>%
mutate(Year = str_replace(Year, "GVC", "")) %>%
rename(country = X) %>%
rename(Insertión = value)
Gdp_current <-"NY.GDP.MKTP.CD"
PBI<-wb_data(indicator= Gdp_current,start_date = 1990, end_date = 2018,country = "countries_only") %>%
pivot_wider(names_from = date,values_from = NY.GDP.MKTP.CD) %>%
filter( is.na(footnote)) %>%
mutate_if(~ any("iso3c" == "ISR"), list(`1990` = ~ PBI$`1995`))
PBI$"1990"[PBI$iso3c == "ISR"]<- 104892955202
PBI_per<-PBI
columnas_anio <- grep("^\\d{4}$", names(PBI_per))
for (i in columnas_anio) {
nombre_columna <- names(PBI_per)[i]
PBI_per[[paste0(nombre_columna, "%")]] <- (PBI_per[[nombre_columna]] / PBI_per$`1990`) * 100
}
PBI_per <- PBI_per %>%
select(iso3c, country, "1990%","1995%","2000%","2008%","2018%" ) %>%
pivot_longer(names_to = "Year",cols = contains("%")) %>%
mutate(Year = str_replace(Year, "%", ""))
total_2018<- sum(PBI$"2018", na.rm = TRUE)
PBI_list <- PBI %>%
select(iso3c, country, `2018`) %>%
mutate(percentage = `2018` / total_2018 * 100) %>%
arrange(desc(percentage)) %>%
mutate(NG_SG = case_when(
iso3c %in% c("DZA", "ARG", "BGD", "BRA", "CHL", "CHN", "COL", "CZE", "EGY", "HKG", "HUN", "IND", "IDN", "IRN", "IRQ", "KAZ", "MYS", "MEX", "NGA", "PAK", "PER", "PHL", "POL", "ROU", "RUS", "SAU", "SGP", "ZAF", "KOR", "THA", "TUR", "VEN", "VNM", "KWT", "QAT", "ARE") ~ "GS",
iso3c %in% c("AUS", "AUT", "BEL", "CAN", "DNK", "FIN", "FRA", "DEU", "GRC", "IRL", "ISR", "ITA", "JPN", "NLD", "NZL", "NOR", "PRT", "ESP", "SWE", "CHE", "GBR", "UKR", "USA", "LUX", "ISL", "MCO") ~ "GN",
TRUE ~ "GS")) %>%
mutate(X = case_when(
iso3c == "DZA" ~ "Algeria",
iso3c == "ARG" ~ "Argentina",
iso3c == "AUS" ~ "Australia",
iso3c == "AUT" ~ "Austria",
iso3c == "BGD" ~ "Bangladesh",
iso3c == "BEL" ~ "Belgium",
iso3c == "BRA" ~ "Brazil",
iso3c == "CAN" ~ "Canada",
iso3c == "CHL" ~ "Chile",
iso3c == "CHN" ~ "China",
iso3c == "COL" ~ "Colombia",
iso3c == "CZE" ~ "Czech Republic",
iso3c == "DNK" ~ "Denmark",
iso3c == "EGY" ~ "Egypt",
iso3c == "FIN" ~ "Finland",
iso3c == "FRA" ~ "France",
iso3c == "DEU" ~ "Germany",
iso3c == "GRC" ~ "Greece",
iso3c == "HKG" ~ "Hong Kong",
iso3c == "HUN" ~ "Hungary",
iso3c == "IND" ~ "India",
iso3c == "IDN" ~ "Indonesia",
iso3c == "IRN" ~ "Iran",
iso3c == "IRQ" ~ "Iraq",
iso3c == "IRL" ~ "Ireland",
iso3c == "ISR" ~ "Israel",
iso3c == "ITA" ~ "Italy",
iso3c == "JPN" ~ "Japan",
iso3c == "KAZ" ~ "Kazakhstan",
iso3c == "MYS" ~ "Malaysia",
iso3c == "MEX" ~ "Mexico",
iso3c == "NLD" ~ "Netherlands",
iso3c == "NZL" ~ "New Zealand",
iso3c == "NGA" ~ "Nigeria",
iso3c == "NOR" ~ "Norway",
iso3c == "PAK" ~ "Pakistan",
iso3c == "PER" ~ "Peru",
iso3c == "PHL" ~ "Philippines",
iso3c == "POL" ~ "Poland",
iso3c == "PRT" ~ "Portugal",
iso3c == "ROU" ~ "Romania",
iso3c == "RUS" ~ "Russia",
iso3c == "SAU" ~ "Saudi Arabia",
iso3c == "SGP" ~ "Singapore",
iso3c == "ZAF" ~ "South Africa",
iso3c == "KOR" ~ "South Korea",
iso3c == "ESP" ~ "Spain",
iso3c == "SWE" ~ "Sweden",
iso3c == "CHE" ~ "Switzerland",
iso3c == "THA" ~ "Thailand",
iso3c == "TUR" ~ "Turkey",
iso3c == "GBR" ~ "UK",
iso3c == "UKR" ~ "Ukraine",
iso3c == "USA" ~ "USA",
iso3c == "VEN" ~ "Venezuela",
iso3c == "VNM" ~ "Viet Nam",
iso3c == "KWT" ~ "Kuwait",
iso3c == "QAT" ~ "Qatar",
iso3c == "ARE"~ "UAE",
))
list<-PBI_list %>%
slice_head(n = 48) %>%
select(iso3c,country,NG_SG,X) %>%
rename(country_s = country) %>%
rename (country = X)
PBI_CGV<- list %>%
left_join(GVC, by = "country")
PBI_CGV<- PBI_CGV %>%
left_join(PBI_per, by = c("iso3c", "Year")) %>%
select(!contains(".")) %>%
rename(Country = country_s,
PBI_Var = value)
intercepts<- PBI_CGV %>%
filter(Year == 2018) %>%
summarise(median_PBI_Var = median(PBI_Var, na.rm = TRUE),
median_Insertión = median(Insertión, na.rm = TRUE))
classification <- PBI_CGV %>%
filter(Year == 2018) %>%
mutate(cuadrant = case_when (
Insertión < intercepts$median_Insertión & PBI_Var > intercepts$median_PBI_Var ~ "High Growth without Insertion",
Insertión > intercepts$median_Insertión & PBI_Var > intercepts$median_PBI_Var ~ "High Growth with Insertion",
Insertión < intercepts$median_Insertión & PBI_Var < intercepts$median_PBI_Var ~ "Low Growth without Insertion",
Insertión > intercepts$median_Insertión & PBI_Var < intercepts$median_PBI_Var ~ "Low Growth with Insertion"))%>%
select(iso3c,cuadrant) %>%
mutate(cuadrant = factor(cuadrant, levels = c("High Growth without Insertion","High Growth with Insertion","Low Growth without Insertion","Low Growth with Insertion")))
PBI_CGV<-PBI_CGV %>%
left_join(classification, by = "iso3c" )
FVA_per<-GVC_base %>%
summarise(across(starts_with("FVA") | starts_with("VA_"), sum)) %>%
select(starts_with("FVA")) %>%
pivot_longer(everything(), values_to = "FVA") %>%
separate(col = "name",into = c("Algo", "Año"),sep = 3 ) %>%
select(2:3)
VA_per<-GVC_base %>%
summarise(across(starts_with("FVA") | starts_with("VA_"), sum)) %>%
select(starts_with("VA_")) %>%
pivot_longer(everything(), values_to = "VA_") %>%
separate(col = "name",into = c("Algo", "Año"),sep = 6 ) %>%
select(2:3)
FVA_def <- FVA_per %>%
left_join(VA_per, by = "Año") %>%
mutate(FVA_per = round(FVA/VA_ * 100, 1)) %>%
select(c("Año", "FVA_per")) %>%
mutate(Año = as.numeric(Año))
rm("FVA_per","VA_per")
Gdp_current <-"NY.GDP.MKTP.CD"
PBI_2<-wb_data(indicator= Gdp_current,start_date = 1990, end_date = 2018,country = "all") %>%
filter(iso3c == "WLD") %>%
select(c("date","NY.GDP.MKTP.CD")) %>%
rename("Año" = "date",
"PBI" = "NY.GDP.MKTP.CD")
PBI_FVA<- PBI_2 %>%
left_join(FVA_def, by = "Año" )
Figure_1 <- ggplot(PBI_FVA, aes(x = Año)) +
geom_bar(aes(y = PBI/1000000000), stat = "identity", fill = "#BDBDBD") +
geom_line(aes(y = FVA_per* 1900, group = 3), color = "#616161", lwd = 1.3, linetype = 7) +
geom_text(aes(y = FVA_per * 1900 + 2000, label = paste0(round(FVA_per, 2), "%")), size = 3, fontface = "bold") +
geom_text(aes(y = PBI/2000000000, label = paste0(round(PBI/1000000000000, 0))), size = 5, color = "white",fontface = "bold") +
scale_y_continuous(sec.axis = sec_axis(~./1900, name = "FVA in %")) +
scale_x_continuous(breaks =c(1990,1991,1992,1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018)) +
theme_minimal() +
theme(
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.title.y.right = element_blank(),
axis.title.y.left = element_blank(),
axis.text.y.right =element_blank(),
axis.text.y.left = element_blank(),
axis.text.x = element_text(size = 10, color = "black"),
axis.title.x = element_blank())
Figure_1
PBI_NGSG <- PBI %>%
left_join(PBI_list, by = "iso3c") %>%
rename("2018" = "2018.x") %>%
select(iso3c, NG_SG, c(`1990`:`2018`)) %>%
pivot_longer(cols = c(`1990`:`2018`),
names_to = "year",
values_to = "GDP") %>%
mutate(year = as.numeric(year)) %>%
group_by(NG_SG, year) %>%
summarise(GDP = sum(GDP, na.rm = TRUE))
Figure_2 <- PBI_NGSG %>%
ggplot(aes(x = year, y = GDP/1000000000000, fill = NG_SG)) +
geom_area(position = "jitter") +
geom_line(data = PBI_NGSG %>% filter(NG_SG == "GS"), aes(group = 1), lwd = 1.5, color = "white", lineend = "round", linejoin = "round")+
scale_y_continuous(labels = label_number(suffix = "B")) +
scale_x_continuous(breaks = c(1990:2018)) +
scale_fill_manual(values = c("#616161", "#BDBDBD")) +
theme_minimal() +
theme(
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.title.x = element_blank(),
axis.title.y = element_blank(),
legend.title = element_blank(),
legend.position = c(.10,.90))
Figure_2
# Figure_3.1 <- ggplot(PBI_CGV %>% arrange(Year)) +
# geom_ribbon(aes(x = Insertión, y = PBI_Var, ymin = min(PBI_Var), ymax = intercepts$median_PBI_Var, xmax =max(Insertión)),fill = "#CCCCCC", alpha = 0.5) +
# geom_ribbon(aes(x = Insertión, y = PBI_Var, xmin = intercepts$median_Insertión, xmax = max(Insertión)),fill ="#CCCCCC", alpha = 0.5)+
# geom_path(aes(x = Insertión, y = PBI_Var, group = iso3c, color = NG_SG),
# arrow = arrow(length = unit(0.10, "inches")), lwd = 1.8, alpha = 1,
# lineend = "round", linejoin = "round") +
# geom_path(aes(x = Insertión, y = PBI_Var, group = iso3c),
# arrow = arrow(length = unit(0.10, "inches")), lwd = 0.5, alpha = 0.5,
# lineend = "round", linejoin = "round", color ="black") +
# geom_text_repel(data = PBI_CGV %>% filter(Year == 2018), aes(x = Insertión, y = PBI_Var, label = iso3c), size = 3, color = "black", fontface='bold') +
# geom_vline(xintercept = intercepts$median_Insertión) +
# geom_hline(yintercept = intercepts$median_PBI_Var) +
# geom_richtext(aes(x = 0.4 , y = 50),label = "Low Growth without Insertion")+
# geom_richtext(aes(x = 0.4 , y = 4800),label = "High Growth without Insertion")+
# geom_richtext(aes(x = 0.7 , y = 4800),label = "High Growth with Insertion")+
# geom_richtext(aes(x = 0.7 , y = 50),label = "Low Growth with Insertion")+
# labs(x = "Insertión in GVC", y = expression(paste("GDP Growth.", ~italic("1990 = 100%"))), color = " ") +
# scale_y_continuous(trans = "log10", limits = c(50, 5000), labels = function(x) paste0(x, "%")) +
# scale_x_continuous(labels = scales::percent) +
# scale_color_manual(values = c("GN" = "#616161", "GS" = "#BDBDBD")) +
# theme_minimal() +
# theme(
# panel.grid.major = element_blank(),
# panel.grid.minor = element_blank(),
# legend.position = c(.10,.90))
#
# Figure_3.1
# rm(Figure_3.1)
Figure_3 <-PBI_CGV %>% arrange(Year) %>%
ggplot()+
geom_vline(xintercept = intercepts$median_Insertión)+
geom_hline(yintercept = intercepts$median_PBI_Var)+
geom_path(aes(x = Insertión, y = PBI_Var, group = iso3c),
arrow = arrow(length = unit(0.10, "inches")), lwd = 1.7,lineend = "round", linejoin = "round", color ="black")+
geom_path(aes(x = Insertión, y = PBI_Var, group = iso3c, color = NG_SG), arrow = arrow(length = unit(0.10, "inches")), lwd = 1.3, lineend = "round", linejoin = "round")+
geom_text_repel(data = PBI_CGV %>% filter(Year == 2018), aes(x = Insertión, y = PBI_Var, label = iso3c), size = 3,color = "black", fontface='bold')+
gghighlight() +
facet_wrap(~ cuadrant)+
labs(x = "Insertión in GVC", y = expression(paste("GDP Growth.", ~italic("1990 = 100%"))), color = " ") +
scale_y_continuous(trans = "log10", limits = c(50, 5000), labels = function(x) paste0(x, "%")) +
scale_x_continuous(labels = scales::percent) +
theme(
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
legend.position = "bottom",
strip.text.x = element_text(size = 10, color = "black", face = "bold"))
Figure_3
PBI_CGV_E <- PBI_CGV %>%
filter (cuadrant == "Low Growth without Insertion") %>%
group_by(Country) %>%
summarise(n())
PBI_CGV_E <- PBI_CGV %>%
filter (cuadrant == "Low Growth without Insertion") %>%
summarise(mean(Insertión),
mean(PBI_Var))
PBI_CGV_E<-PBI_CGV %>%
select(iso3c,Year,Insertión,PBI_Var) %>%
unite(col = "country", c("iso3c","Year"), sep = "_") %>%
mutate(PBI_Var = PBI_Var,
PBI_Var2 = log(PBI_Var)) %>%
filter(!grepl("1990", country))
PBI_CGV_E<-PBI_CGV %>%
select(iso3c,Year,Insertión,PBI_Var) %>%
unite(col = "country", c("iso3c","Year"), sep = "_") %>%
mutate(PBI_Var = PBI_Var,
PBI_Var2 = log(PBI_Var)) %>%
filter(!grepl("1990", country))
WSS <- fviz_nbclust(scale(PBI_CGV_E[,-c(1,3)]), kmeans, method = "wss") + ggtitle("WSS") +
theme(plot.title = element_text(face = "bold"))
Silouttes <- fviz_nbclust(scale(PBI_CGV_E[,-c(1,3)]), kmeans, method = "silhouette") + ggtitle("Silhouette") +
theme(plot.title = element_text(face = "bold"))
Cetreoide <- grid.arrange(WSS, Silouttes, ncol = 2)
km <- kmeans(scale(PBI_CGV_E[,-c(1,3)]), centers = 3, nstart = 50)
PBI_CGV_E<-PBI_CGV_E %>%
cbind(km$cluster) %>%
rename("cluster"="km$cluster" ) %>%
mutate(cluster = case_when( cluster == 1 ~ "Cluster 1",
cluster == 2 ~ "Cluster 2",
cluster == 3 ~ "Cluster 3"))
Table_3 <- PBI_CGV_E %>%
mutate(cluster = case_when(
cluster == "Cluster 1" ~ 1 ,
cluster == "Cluster 2" ~ 2 ,
cluster == "Cluster 3" ~ 3
)) %>%
separate("country", into = c("iso3c", "year"), sep = "_") %>%
left_join(list) %>%
select(iso3c, year, cluster, NG_SG) %>%
pivot_wider(names_from = year, values_from = cluster) %>%
select("iso3c", "1995","2000","2008","2018", "NG_SG") %>%
unite(col = "Trayectory", c("1995","2000","2008","2018"), sep=",") %>%
group_by(Trayectory) %>%
summarise(
Cant. = n(),
Countries = paste(iso3c, collapse = ", "),
Count_NG = sum(NG_SG == "GN"),
Count_SG = sum(NG_SG == "GS")
) %>%
arrange(desc(Cant.)) %>%
mutate(
count_total_NG = sum(Count_NG),
count_total_SG = sum(Count_SG),
Proportion_SG = sprintf("%.2f%%", (Count_SG / count_total_SG) * 100),
Proportion_NG = sprintf("%.2f%%", (Count_NG / count_total_NG) * 100),
"N°" = row_number()
) %>%
select("N°", "Trayectory", "Cant.", "Countries", "Proportion_NG", "Proportion_SG")
Table_3
## # A tibble: 12 × 6
## `N°` Trayectory Cant. Countries Proportion_NG Proportion_SG
## <int> <chr> <int> <chr> <chr> <chr>
## 1 1 3,3,2,2 13 IND, BRA, AUS, MEX, IDN, … 5.00% 42.86%
## 2 2 3,3,1,1 10 DEU, GBR, FRA, RUS, ESP, … 40.00% 7.14%
## 3 3 1,1,1,1 8 NLD, BEL, AUT, NOR, IRL, … 25.00% 10.71%
## 4 4 1,1,1,2 3 POL, MYS, PHL 0.00% 10.71%
## 5 5 3,3,1,2 3 KOR, THA, ROU 0.00% 10.71%
## 6 6 3,3,3,2 3 USA, ARG, BGD 5.00% 7.14%
## 7 7 3,1,1,1 2 SWE, DNK 10.00% 0.00%
## 8 8 3,3,3,3 2 JPN, CAN 10.00% 0.00%
## 9 9 2,2,2,2 1 VNM 0.00% 3.57%
## 10 10 3,2,2,2 1 CHN 0.00% 3.57%
## 11 11 3,3,1,3 1 ITA 5.00% 0.00%
## 12 12 3,3,2,3 1 IRN 0.00% 3.57%
Table_2 <- aggregate(PBI_CGV_E[-4], by=list(cluster=km$cluster), mean)
Figure_8 <- PBI_CGV_E %>%
ggplot(aes(x = Insertión, y = PBI_Var, colour = factor(cluster))) +
geom_point(size = 3, color = "black") +
geom_point(size = 1.5) +
stat_ellipse(type = "norm", linetype = 2) +
stat_ellipse(type = "t", geom = "polygon",
aes(fill = factor(cluster)), alpha = 0.25) +
geom_text_repel(data = PBI_CGV_E %>% filter(!grepl("1990", country)), aes(label = country), color = "black", size = 2.5)+
gghighlight() +
facet_wrap(vars(cluster)) + # Se corrige aquÃ
labs(x = "Insertión in GVC", y = expression(paste("GDP Growth.", ~italic("1990 = 100%")))) +
scale_y_continuous(trans = "log10", labels = function(x) paste0(x, "%")) +
scale_x_continuous(labels = scales::percent) +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
legend.position = "none",
strip.text.x = element_text(size = 10, color = "black", face = "bold"))
Figure_8
table_3_png <- tableGrob(Table_3)
table_2_png <- tableGrob(Table_2)
ggsave(filename = "Figure_1.png", plot = Figure_1, bg = "white", width = 12, height = 6)
ggsave(filename = "Figure_2.png", plot = Figure_2, bg = "white", width = 12, height = 6)
ggsave(filename = "Figure_3.png", plot = Figure_3, bg = "white", width = 12, height = 12)
ggsave(filename = "Figure_5.png", plot = Figure_8, bg = "white", width = 12, height = 8)
ggsave(filename = "Figure_4.png", plot = Cetreoide, bg = "white", width = 10, height = 4)
ggsave("table_3.png", table_3_png , width = 14, height = 4, dpi = 300)
ggsave("table_2.png", table_2_png , width = 10, height = 4, dpi = 300)