UN Comtrade is a repository of official international trade statistics and relevant analytical tables. It allows to view and download detailed global trade data, i.e. imports and exports of all goods or even of specific services or goods (say tomatoes).
comtradr is a R package and a collection of functions for interacting with the UN Comtrade API. Besides comtradr we use various other packages that we shall load first.
library(tidyverse)
library(comtradr)
library(visNetwork)
library(grid)
library(png)
library(RCurl)
library(scales)
billion <- function(value) {
value/1000000000
}
q <- ct_search(reporters = "USA",
partners = c("Germany", "France", "Japan", "Mexico"),
trade_direction = "imports")
The main function is ct_search()
. It accepts the following arguments:
ct_country_lookup()
to look up the name of a country, e.g. ct_country_lookup("russia")
ct_commodity_lookup()
to look up codes, e.g. tomatoes <- ct_commodity_lookup("tomato")
.tomatoes
can then be used as a variable for the argumentct_register_token()
)Without API token you got 100 requests per day, check how many are left with ct_get_remaining_hourly_queries()
.
q %>% glimpse()
## Observations: 112
## Variables: 35
## $ classification <chr> "H5", "H5", "H5", "H5", "H5", "H5", "H5",…
## $ year <int> 2017, 2017, 2017, 2017, 2018, 2018, 2018,…
## $ period <int> 2017, 2017, 2017, 2017, 2018, 2018, 2018,…
## $ period_desc <chr> "2017", "2017", "2017", "2017", "2018", "…
## $ aggregate_level <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ is_leaf_code <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ trade_flow_code <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,…
## $ trade_flow <chr> "Import", "Import", "Import", "Import", "…
## $ reporter_code <int> 842, 842, 842, 842, 842, 842, 842, 842, 8…
## $ reporter <chr> "USA", "USA", "USA", "USA", "USA", "USA",…
## $ reporter_iso <chr> "USA", "USA", "USA", "USA", "USA", "USA",…
## $ partner_code <int> 251, 276, 392, 484, 251, 276, 392, 484, 2…
## $ partner <chr> "France", "Germany", "Japan", "Mexico", "…
## $ partner_iso <chr> "FRA", "DEU", "JPN", "MEX", "FRA", "DEU",…
## $ second_partner_code <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ second_partner <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ second_partner_iso <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ customs_proc_code <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ customs <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ mode_of_transport_code <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ mode_of_transport <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ commodity_code <chr> "TOTAL", "TOTAL", "TOTAL", "TOTAL", "TOTA…
## $ commodity <chr> "All Commodities", "All Commodities", "Al…
## $ qty_unit_code <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,…
## $ qty_unit <chr> "No Quantity", "No Quantity", "No Quantit…
## $ alt_qty_unit_code <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ alt_qty_unit <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ qty <int> 0, 0, 0, 0, 0, 0, 0, 0, NA, NA, NA, NA, N…
## $ alt_qty <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ netweight_kg <int> 0, 0, 0, 0, 0, 0, 0, 0, NA, NA, NA, NA, N…
## $ gross_weight_kg <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ trade_value_usd <dbl> 50036407688, 119991393155, 139797020593, …
## $ cif_trade_value_usd <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ fob_trade_value_usd <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ flag <int> 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0,…
q %>%
as_tibble() %>%
filter(reporter == "USA", partner %in% c("Germany", "Mexico")) %>%
select(trade_value_usd, reporter, partner, everything()) %>%
ggplot(aes(x = year, y = trade_value_usd/1000000000, fill = partner)) +
geom_col(alpha = 0.6, position = "dodge") +
scale_y_continuous(labels = scales::number) +
scale_x_continuous(breaks = seq(1990, 2018, 2)) +
labs(title = "US imports from Germany and from Mexico", y = "billion USD") +
theme_bw()
us1 <- ct_search(reporters = "USA",
partners = "All",
trade_direction = c("imports", "exports"),
freq = "annual",
start_date = (2018-4),
end_date = 2018)
us2 <- ct_search(reporters = "USA",
partners = "All",
trade_direction = c("imports", "exports"),
freq = "annual",
start_date = (2013-4),
end_date = 2013)
us3 <- ct_search(reporters = "USA",
partners = "All",
trade_direction = c("imports", "exports"),
freq = "annual",
start_date = (2008-4),
end_date = 2008)
us4 <- ct_search(reporters = "USA",
partners = "All",
trade_direction = c("imports", "exports"),
freq = "annual",
start_date = (2003-4),
end_date = 2003)
us5 <- ct_search(reporters = "USA",
partners = "All",
trade_direction = c("imports", "exports"),
freq = "annual",
start_date = (1998-4),
end_date = 1998)
us <- bind_rows(us1, us2, us3, us4, us5) %>% distinct()
us %>% saveRDS("data/us.RDS")
data1 <- us %>% #distinct() %>%
filter(partner_iso != "WLD") %>%
mutate(trade_value_usd_bn = billion(trade_value_usd)) %>%
group_by(trade_flow, year) %>%
summarise(trade_value_usd_bn = sum(trade_value_usd_bn, na.rm = T))
data1 %>%
ggplot(aes(x = year, y = trade_value_usd_bn, color = trade_flow)) +
# geom_area(alpha = 0.1, position = "identity") +
geom_line() +
geom_point() +
scale_y_continuous(labels = scales::number, breaks = seq(0, 2500, 500)) +
scale_color_manual(values = c("#88be3f", "#02a7eb")) +
scale_x_continuous(breaks = seq(1990, 2018, 2), expand = c(0.01, 0.01)) +
labs(title = "USA import and exports over time",
x = "", y = "trade value in billion USD", caption = "Data: UN Comtrade", color = "", fill = "")
In 2018 the balance of trade in goods was in deficit by -933
Current account? What about services?
srv <- ct_search(reporters = "USA",
partners = "All",
trade_direction = c("imports", "exports"),
type = "services",
freq = "annual",
start_date = (2018-4),
end_date = 2018)
# srv %>% saveRDS("data/srv.RDS")
services <- srv %>% as_tibble() %>%
filter(partner == "World") %>%
group_by(year, trade_flow) %>%
summarise(trade_value_usd_bn = sum(trade_value_usd)/1000000000) %>%
spread(trade_flow, trade_value_usd_bn)
Of course, there’s more to the current account than just the trade in good. There’s trade in services, the countrie’s income abroad, and current transfers. For the former we have the latest data from Cometrade dates from 2016. The US imported services of 496 billion USD while it exported services for 727 bn USD. The surplus here is 231 bn USD.
To put this into perspective, the balance of trade in goods was at -783. The balance of trade goods and services would therefore be -552 bn USD (2016).
We shall focus on the exchange of goods in the following.
Who are the US’ main trading partners?
Prepare a function trade_plot()
for plotting the trade data.
# function similar to annotation_custom() but specifying data
annotation_custom2 <- function (grob, xmin = -Inf, xmax = Inf,
ymin = -Inf, ymax = Inf,
data) {
layer(data = data,
stat = StatIdentity,
position = PositionIdentity,
geom = ggplot2:::GeomCustomAnn,
inherit.aes = TRUE, params = list(grob = grob,
xmin = xmin, xmax = xmax,
ymin = ymin, ymax = ymax))
}
percent2 <- function(input) {
if (is.numeric(input)) {
output <- percent(input)
} else {
output <- input
}
return(output)
}
number2 <- function(input) {
if (is.numeric(input)) {
output <- number(input)
} else {
output <- input
}
return(output)
}
trade_plot <- function(data, yr = 2018, top_n = 8, include_others = T, include_flags = T, include_share = T, title = "USA import and exports") {
if (top_n) {
o <- "Others"
} else {
o <- "Rest of the world"
}
top_partners <- data %>%
filter(partner_iso != "WLD", year == year) %>%
group_by(partner_iso) %>%
tally(trade_value_usd, sort = T) %>%
top_n(top_n) %>%
pull(partner_iso)
if (include_others) {
others <- data %>%
filter(year == yr, !(partner_iso %in% top_partners), partner_iso != "WLD") %>%
group_by(trade_flow) %>%
summarise(trade_value_usd = sum(trade_value_usd)) %>%
mutate(partner_iso = o, partner = o, year = yr)
toplot <- data %>%
filter(year == yr, partner_iso %in% top_partners) %>%
bind_rows(others) %>%
mutate(partner_iso_fac = factor(partner_iso, levels = c(top_partners, o)))
} else {
toplot <- data %>%
filter(year == yr, partner_iso %in% top_partners) %>%
mutate(partner_iso_fac = factor(partner_iso, levels = c(top_partners)))
}
toplot <- toplot %>%
ungroup() %>%
mutate(trade_value_usd_bn = billion(trade_value_usd))
if (include_share) {
toplot <- toplot %>%
group_by(trade_flow) %>%
mutate(share_of_total = trade_value_usd_bn/sum(trade_value_usd_bn)) %>%
ungroup()
} else {
toplot <- toplot %>%
mutate(share_of_total = "")
}
p <- toplot %>%
group_by(partner_iso, trade_flow) %>%
mutate(label_pos = max(trade_value_usd_bn/2, 100)) %>%
ungroup() %>%
ggplot(aes(y = trade_value_usd_bn, x = trade_flow, fill = trade_flow)) +
geom_col() +
geom_text(aes(label = number(trade_value_usd_bn, big.mark = "'"), y = label_pos), size = 3) +
geom_text(aes(label = percent2(share_of_total),
y = max(trade_value_usd_bn)*0.9), size = 2.5, hjust = -0.2) +
facet_wrap(~partner_iso_fac, dir = "h",
nrow = max(1, ceiling(sqrt(top_n)), na.rm = T),
# ncol = max(1, ceiling((top_n+include_others)/ceiling(sqrt(top_n))), na.rm = T)
) +
scale_fill_manual(values = c("#88be3f", "#02a7eb"))
if (include_flags) {
countries_annotate <- toplot %>%
select(partner_iso, partner) %>%
distinct() %>%
mutate(path = paste0("./flags/", str_replace_all(partner, " ", "_"), ".png"))
max_y <- max(toplot$trade_value_usd_bn, na.rm = T)
for (i in 1:top_n) {
if (!top_n) { next() }
data_annotate <- tibble(partner_iso_fac = factor(countries_annotate[i, "partner_iso"], levels = c(top_partners, o)),
trade_flow = "Export", trade_value_usd_bn = 1)
if (file.exists(pull(countries_annotate[i, "path"]))) {
# print(paste0(pull(countries_annotate[i, "path"]), " exists and should be plotted"))
img <- readPNG(pull(countries_annotate[i, "path"]))
p <- p +
annotation_custom2(rasterGrob(img, interpolate=TRUE),
ymax = max_y, ymin = max_y*0.8,
xmin = -1, data = data_annotate)
} else {
next()
}
}
}
p <- p +
labs(x = "", y = "",
title = title, subtitle = paste0("trade value in goods in billion USD, year: ", yr),
caption = "Data: UN Comtrade") +
theme(legend.position = "none") #+
# theme_bw()
return(p)
}
Again here’s the total import and exports for the year 2018.
trade_plot(us, top_n = 0, include_others = T, include_flags = T, include_share = F)
Let’s see the 24 top trading parters
# trade_plot(us, top_n = 25, include_others = F, include_flags = T)
trade_plot(us, top_n = 24, include_others = T, include_flags = T, include_share = T)
Immediately visible are the imports from China. With 563 bn USD. That’s 21.5% of all US imports. Exports to China (120 bn USD) only account for 7.23% of all exports.
The increase in imports from China is a recent phenomena. It has a lot China economic catching up with the west. See recent history on Wikipedia.
Here’s the imports from the 5 todays major trading partners:
top_5 <- us %>%
filter(partner_iso != "WLD", year == 2018) %>%
group_by(partner_iso) %>%
tally(trade_value_usd, sort = T) %>%
top_n(5) %>%
pull(partner_iso)
us %>%
filter(partner_iso %in% top_5, trade_flow == "Import") %>%
ggplot(aes(x = year, y = billion(trade_value_usd), color = partner_iso)) +
geom_line() +
scale_x_continuous(breaks = seq(1992, 2018, 2)) +
labs(title = "US imports of the current top-5 trading partners",
x = "", y = "trade value in billion USD", color = "",
caption = "Date: UN Comtrade")
It’s also interesting to view it as share of total imports.
top_5 <- us %>%
filter(partner_iso != "WLD", year == 2018) %>%
group_by(partner_iso) %>%
tally(trade_value_usd, sort = T) %>%
top_n(5) %>%
pull(partner_iso)
us %>%
filter(partner_iso != "WLD", trade_flow == "Import") %>%
group_by(year) %>%
mutate(share_of_total = trade_value_usd/sum(trade_value_usd)) %>%
ungroup() %>%
filter(partner_iso %in% top_5, trade_flow == "Import") %>%
ggplot(aes(x = year, y = share_of_total, color = partner_iso)) +
geom_line() +
scale_x_continuous(breaks = seq(1992, 2018, 2)) +
scale_y_continuous(labels = scales::percent, breaks = seq(0.04, 0.5, by = 0.02)) +
labs(title = "US imports of the current top-5 trading partners (relative)",
x = "", y = "share of all imports", color = "",
caption = "Date: UN Comtrade")
How does the situation look like from the point of view of China? How much do Chinese rely on the US?
ch1 <- ct_search(reporters = "China",
partners = "All",
trade_direction = c("imports", "exports"),
freq = "annual",
start_date = (2018-4),
end_date = 2018)
ch2 <- ct_search(reporters = "China",
partners = "All",
trade_direction = c("imports", "exports"),
freq = "annual",
start_date = (2013-4),
end_date = 2013)
ch3 <- ct_search(reporters = "China",
partners = "All",
trade_direction = c("imports", "exports"),
freq = "annual",
start_date = (2008-4),
end_date = 2008)
ch4 <- ct_search(reporters = "China",
partners = "All",
trade_direction = c("imports", "exports"),
freq = "annual",
start_date = (2003-4),
end_date = 2003)
ch5 <- ct_search(reporters = "China",
partners = "All",
trade_direction = c("imports", "exports"),
freq = "annual",
start_date = (1998-4),
end_date = 1998)
ch <- bind_rows(ch1, ch2, ch3, ch4, ch5) %>% distinct()
# ch %>% saveRDS("data/ch.RDS")
Note that the most recent annual data for China is 2017.
trade_plot(ch, yr = 2017, top_n = 0, include_others = T, include_flags = T, include_share = F)
trade_plot(ch, yr = 2017, top_n = 24, include_others = T, include_flags = T, include_share = T, title = "China imports and exports")
# CHINA or MEXICO trade with US
data1 <- us %>% #distinct() %>%
filter(partner_iso == "WLD") %>%
mutate(trade_value_usd_bn = billion(trade_value_usd)) %>%
group_by(trade_flow, year) %>%
summarise(trade_value_usd_bn = sum(trade_value_usd_bn, na.rm = T))
# data1 %>%
# ggplot(aes(x = year, y = trade_value_usd_bn, color = trade_flow, fill = trade_flow)) +
# geom_area(alpha = 0.1, position = "identity") +
# geom_point() +
# scale_y_continuous(labels = scales::number, breaks = seq(0, 250, 50)) +
# scale_color_manual(values = c("#88be3f", "#02a7eb")) +
# scale_x_continuous(breaks = seq(1990, 2018, 2), expand = c(0.01, 0.01)) +
# labs(title = "USA import and exports over time",
# x = "", y = "trade value in billion USD", caption = "Data: UN Comtrade", color = "", fill = "")
data2 <- ch %>% #distinct() %>%
filter(partner_iso != "WLD") %>%
mutate(trade_value_usd_bn = billion(trade_value_usd)) %>%
group_by(trade_flow, year) %>%
summarise(trade_value_usd_bn = sum(trade_value_usd_bn, na.rm = T))
# data2 %>%
# ggplot(aes(x = year, y = trade_value_usd_bn, color = trade_flow, fill = trade_flow)) +
# geom_area(alpha = 0.1, position = "identity") +
# geom_point() +
# scale_y_continuous(labels = scales::number, breaks = seq(0, 2500, 500)) +
# scale_color_manual(values = c("#88be3f", "#02a7eb")) +
# scale_x_continuous(breaks = seq(1990, 2018, 2), expand = c(0.01, 0.01)) +
# labs(title = "USA import and exports over time",
# x = "", y = "trade value in billion USD", caption = "Data: UN Comtrade", color = "", fill = "")
bind_rows(
data1 %>% mutate(reporter = "USA"),
data2 %>% mutate(reporter = "China")
) %>%
ggplot(aes(x = year, y = trade_value_usd_bn, color = interaction(trade_flow, reporter), fill = interaction(trade_flow, reporter))) +
geom_line() +
# geom_area(alpha = 0.1, position = "identity") +
geom_point(aes(shape = reporter)) +
geom_vline(xintercept = 2007, alpha = 0.3) +
geom_text(label = "China exports > US exports", x = 2007, y = 0, inherit.aes = F, color = "grey",
angle = 90, vjust = 1, hjust = -0.05) +
scale_y_continuous(labels = scales::number, breaks = seq(0, 2500, 500)) +
scale_color_manual(values = c("#ca0020", "#f4a582", "#0571b0", "#92c5de")) +
scale_x_continuous(breaks = seq(1990, 2018, 2), expand = c(0.01, 0.01)) +
scale_shape(guide = "none") +
labs(title = "USA and China world trade over time",
x = "", y = "trade value in billion USD", caption = "Data: UN Comtrade", color = "", fill = "")
# # There are libraries for loading data from World Bank Indicators, but I encountered issues.
# # Therefore we shall download data from https://databank.worldbank.org/data/reports.aspx?source=2&series=NY.GDP.MKTP.CD#
# library(WDI)
# library(wbstats)
gdp <- read_csv("data/gdp.csv")
gdp <- gdp %>%
filter(str_detect(`Series Name`, "GDP")) %>%
select(-`2018 [YR2018]`) %>%
gather(year, gdp, -`Series Name`, -`Series Code`, -`Country Name`, -`Country Code`) %>%
select(-`Series Name`, -`Series Code`) %>%
mutate(year = str_sub(year, 1, 4) %>% as.integer(),
gdp_label = ifelse(year == 2017, number2(billion(gdp)), ""))
gdp %>%
ggplot(aes(x = year, y = billion(gdp), color = `Country Name`)) +
geom_line() +
scale_color_manual(values = c("red", "blue")) +
scale_y_continuous(labels = scales::number, breaks = seq(0, 20000, by = 2500)) +
scale_x_continuous(breaks = seq(1968, 2018, by = 4)) +
geom_vline(xintercept = 1976, color = "grey") +
geom_text(label = "end of Mao era", x = 1976, y = 0, inherit.aes = F, color = "grey",
angle = 90, vjust = 1, hjust = -1) +
geom_vline(xintercept = 1989, color = "grey") +
geom_text(label = "China rising power", x = 1989, y = 0, inherit.aes = F, color = "grey",
angle = 90, vjust = 1, hjust = -1) +
geom_vline(xintercept = 2008, color = "grey") +
geom_text(label = "2008 Olympics Beijing", x = 2008, y = 0, inherit.aes = F, color = "grey",
angle = 90, vjust = 1, hjust = -1) +
geom_vline(xintercept = 2012.7, color = "grey") +
geom_text(label = "Xi Jinping", x = 2012.7, y = 0, inherit.aes = F, color = "grey",
angle = 90, vjust = 1, hjust = -1) +
geom_text(aes(label = gdp_label)) +
labs(title = "GDP over time",
subtitle = "China and USA, unadjusted",
x = "", y = "GDP in billion USD",
color = "",
caption = "Data: World Bank Indicators")
What goods do the USA import from China?
com1 <- tibble()
for (i in 0:4) {
codes <- c(1:20) + i*20
com1 <- com1 %>%
bind_rows(ct_search(reporters = "USA",
partners = "China",
start_date = "2018",
end_date = "2018",
trade_direction = c("imports", "exports"),
commod_codes = str_pad(codes, 2, "left", "0")))
print("sleep 10 secs")
Sys.sleep(10)
}
com %>% saveRDS("data/com.RDS")
top_com <- com %>%
group_by(commodity) %>%
tally(trade_value_usd, sort = T) %>%
top_n(10) %>%
pull(commodity)
others <- com %>%
filter(!(commodity %in% top_com)) %>%
group_by(trade_flow) %>%
summarise(trade_value_usd = sum(trade_value_usd)) %>%
mutate(commodity = "Others")
com %>%
filter(commodity %in% top_com) %>%
bind_rows(others) %>%
mutate(trade_value_usd_bn = billion(trade_value_usd)) %>%
select(trade_flow, trade_value_usd_bn, commodity) %>%
# arrange(-trade_value_usd) %>%
ggplot(aes(y = trade_value_usd_bn, x = trade_flow, fill = factor(str_sub(commodity, 1, 35), levels = str_sub(c(top_com, "Others"), 1, 35)))) +
geom_col() +
geom_text(aes(label = number(trade_value_usd_bn)), position = position_stack(vjust = .5)) +
scale_fill_brewer(palette = "Set3") +
scale_y_continuous(labels = scales::number) +
labs(title = "Classification by goods traded",
subtitle = "reporter: USA, partner: China, year 2018",
x = "", y = "Cumulated trade value in billion USD",
fill = "",
caption = "Data: UN Comtrade")
Let’s make a visNetwork graph.
data <- us %>% filter(year == 2018, partner != "World")
edges <- bind_rows(
# exports
data %>%
filter(trade_flow == "Export") %>%
select(from = reporter, to = partner, value = trade_value_usd) %>%
arrange(desc(value)),
# imports
data %>%
filter(trade_flow == "Import") %>%
select(from = partner, to = reporter, value = trade_value_usd) %>%
arrange(desc(value))
) %>%
mutate(title = paste0("bn$", number(value/1000000000)))
cutoff <- 38000000000
nodes <- bind_rows(
edges %>%
filter(value >= cutoff) %>%
select(id = from),
edges %>%
filter(value >= cutoff) %>%
select(id = to)
) %>%
unique() %>%
left_join(data %>% filter(year == 2018) %>% select(id = partner, label = partner_iso) %>% unique()) %>%
mutate(shape = "circularImage", image = paste0("./flags/", str_replace_all(id, " ", "_"), ".png"))
visNetwork(nodes, edges, width = "100%") %>%
visEdges(arrows = "from")