library(tidyverse)
library(lubridate)
library(scales)
library(ggrepel)
library(tidyquant)
library(jsonlite)
theme_set(theme_minimal())
invisible(Sys.setlocale("LC_TIME", "en_US.UTF-8"))
library(DT)
library(comtradr) # package changed recently (one needs a API key), see readme https://github.com/ropensci/comtradr
Trump imposed tariffs on a variety of goods. I asked perplexity.ai to list some:
According to basic economic theory, tariffs should lead to higher prices for consumers and lower demand for the goods subject to tariffs. This is because tariffs increase the cost of imported goods, making them more expensive for consumers. In response, consumers may choose to buy fewer of these goods or switch to domestic alternatives. Here’s a graph similar to what I was shown in my first semester economics class:
The graphs shows that the world price (P_world) is lower than the domestic equilibrium price (that’s where the demand and supply curves intersect). The main beneficiaries of a low world price are consumers. This is expressed in a large consumer surplus. With a tariff, the domestic price rises to P_tariff. The consumer surplus shrinks, and the producer surplus grows. The government also benefits from the tariff, as it collects revenue from the tax. However, the total domestic surplus (consumer surplus + producer surplus + government revenue) shrinks. These are labeled “Societal Loss”.
Now if tariffs are set high so the price rises to or above the domestic equilibrium price, there will be no more imports. In that case, of course, there’s no tariff tax revenue. The domestic producer surplus grows, but the consumer surplus shrinks even more. The societal loss is even greater.
The pro-tariff argument is that a large economy like the US can hurt other countries by imposing tariffs. The US with a high standard of living can afford a societal loss, but other countries can’t afford to lose the US market. The US can use tariffs to force other countries to lower their tariffs, or for other (non economic) concessions.
Here’s a good video: https://www.youtube.com/watch?v=_-eHOSq3oqI
The UN Comtrade database provides data on the value of imports and exports for each country and each product category.
# comtradr::country_codes |>
# filter(str_detect(country, "Germany"))
# # iso_3: USA
# # iso_3: CHN
# # iso_3: DEU
set_primary_comtrade_key(read_lines("comtradeprim.txt"))
us_ch <- comtradr::ct_get_data(
reporter = 'USA',
partner = c('CHN'),
start_date = 2013,
end_date = 2023
)
us_ch_monthly <- data.frame()
for (y in 2017:2022) {
temp <- comtradr::ct_get_data(
reporter = 'USA',
partner = c('CHN'),
start_date = y,
end_date = y,
frequency = 'M'
)
us_ch_monthly <- bind_rows(us_ch_monthly, temp)
}
us_ch |> saveRDS("data/tariffs/us_ch.RDS")
us_ch_monthly |> saveRDS("data/tariffs/us_ch_monthly.RDS")
us_ch <- readRDS("data/tariffs/us_ch.RDS")
us_ch_monthly <- readRDS("data/tariffs/us_ch_monthly.RDS")
us_ch |>
ggplot(aes(x = refYear, y = primaryValue/10^9, fill = flowDesc)) +
geom_col(position = "dodge") +
geom_vline(xintercept = c(2018.5, 2019.5), linetype = "dashed") +
annotate("text", x = 2018.5, y = 100, label = "mid 2018", vjust = -1, angle = 90) +
annotate("text", x = 2019.5, y = 100, label = "mid 2019", vjust = -1, angle = 90) +
labs(title = "US-China Trade (reported by US)",
x = "Year",
y = "Value (billion USD)",
color = "Flow") +
scale_y_continuous(labels = scales::dollar) +
scale_x_continuous(breaks = seq(2013, 2023, 1)) +
theme(legend.position = "bottom")
us_ch_monthly |>
mutate(date = ymd(refPeriodId)) |>
ggplot(aes(x = date, y = primaryValue/10^9, color = flowDesc)) +
geom_line() +
geom_vline(xintercept = c(as.Date("2018-07-01"), as.Date("2019-07-01")), linetype = "dashed") +
annotate("text", x = as.Date("2018-07-01"), y = 10, label = "mid 2018", vjust = -1, angle = 90) +
annotate("text", x = as.Date("2019-07-01"), y = 10, label = "mid 2019", vjust = -1, angle = 90) +
labs(title = "US-China Trade (reported by US), monthly",
x = "Year",
y = "Value (billion USD)",
color = "Flow") +
scale_y_continuous(labels = scales::dollar) +
scale_x_date(date_breaks = "1 year", date_labels = "%Y") +
theme(legend.position = "bottom")
The first chart shows the annual trade between the US and China. The second chart shows the monthly trade.
First off, from the monthly line chart it becomes clear that there are seasonal patterns in the trade. Imports increase in the second half of the year, and decrease in the first half.
There’s a large drop in 2020, which however is not only due to tariffs but due to the pandemic. The pandemic also caused a drop in 2021, but trade recovered in 2022. Yet recovery is not as strong as the increase in US prices or GDP, suggesting that the tariffs had an effect.
One of the first tariffs Trump imposed was on washing machines.
# comtradr::ct_get_ref_table('HS') |>
# as_tibble() |>
# filter(str_detect(text, "washing machine"))
# # filter(id == "845020")
# # 8450 - Household or laundry-type washing machines; including machines which both wash and dry
washing_machines <- data.frame()
for (year in 2013:2023) {
cat(year, "\n")
temp <- comtradr::ct_get_data(
reporter = 'USA',
partner = 'CHN',
start_date = year,
end_date = year,
commodity_code = '8450',
frequency = "M"
)
washing_machines <- bind_rows(washing_machines, temp)
}
washing_machines |> saveRDS("data/tariffs/washing_machines.RDS")
washing_machines <- readRDS("data/tariffs/washing_machines.RDS")
washing_machines |>
mutate(date = ymd(refPeriodId)) |>
ggplot(aes(x = date, y = primaryValue/10^6, color = flowDesc)) +
geom_line() +
labs(title = "US-China Trade in Washing Machines",
x = "Year",
y = "Value (million USD)",
color = "Flow") +
scale_y_continuous(labels = scales::dollar) +
scale_x_date(date_breaks = "1 year", date_labels = "%Y") +
theme(legend.position = "bottom")
Data suggests that washing machine imports tanked already in mid-2016. Why is that?
Again according to perplexiy.ai
# comtradr::ct_get_ref_table('HS') |>
# as_tibble() |>
# filter(str_detect(text, "photovoltaic cells|Photovoltaic cells"))
# # 8541
solar_panels <- data.frame()
for (year in 2013:2023) {
cat(year, "\n")
temp <- comtradr::ct_get_data(
reporter = 'USA',
partner = 'CHN',
start_date = year,
end_date = year,
commodity_code = '8541',
frequency = "M"
)
solar_panels <- bind_rows(solar_panels, temp)
}
solar_panels |> saveRDS("data/tariffs/solar_panels.RDS")
solar_panels <- readRDS("data/tariffs/solar_panels.RDS")
solar_panels |>
mutate(date = ymd(refPeriodId)) |>
ggplot(aes(x = date, y = primaryValue/10^6, color = flowDesc)) +
geom_line() +
labs(title = "US-China Trade in Solar Panels",
x = "Year",
y = "Value (million USD)",
color = "Flow") +
scale_y_continuous(labels = scales::dollar) +
scale_x_date(date_breaks = "1 year", date_labels = "%Y") +
theme(legend.position = "bottom")
steel_ids <- comtradr::ct_get_ref_table('HS') |>
as_tibble() |>
filter(str_detect(text, "Steel|steel"),
str_length(id) == 4) |> distinct(id, text)
most_important_steel <- comtradr::ct_get_data(
reporter = 'USA',
# partner = 'ALL',
start_date = 2023,
end_date = 2023,
commodity_code = steel_ids |> pull(id),
frequency = "A"
)
steel_ids |> saveRDS("data/tariffs/steel_ids.RDS")
most_important_steel |> saveRDS("data/tariffs/most_important_steel.RDS")
steel_ids <- readRDS("data/tariffs/steel_ids.RDS")
most_important_steel <- readRDS("data/tariffs/most_important_steel.RDS")
most_important_steel |>
select(refYear, cmdCode, flowDesc, primaryValue) |>
left_join(steel_ids, by = c("cmdCode" = "id")) |>
group_by(refYear, cmdCode, text,
flowDesc = ifelse(flowDesc == "Re-export", "Export", flowDesc)) |>
summarise(primaryValue = sum(primaryValue)) |>
mutate(primaryValue = ifelse(flowDesc == "Import", -primaryValue, primaryValue)) |>
group_by(cmdCode) |>
mutate(tot = sum(primaryValue)) |>
ggplot(aes(x = reorder(cmdCode, primaryValue), y = primaryValue/10^9, fill = flowDesc)) +
geom_col() +
geom_text(aes(label = ifelse(flowDesc == "Import", text, NA_character_)),
y = -9, hjust = 0, position = position_stack(vjust = 0.5)) +
coord_flip() +
labs(title = "US-China Trade in Steel",
x = "Year",
y = "Import | Export\n(billion USD)",
color = "Flow")
# what partners are most important for US steel trade?
steel_partners23 <- comtradr::ct_get_data(
reporter = 'USA',
partner = "all_countries",
start_date = 2023,
end_date = 2023,
commodity_code = "7308",
frequency = "A"
)
steel_partners13 <- comtradr::ct_get_data(
reporter = 'USA',
partner = "all_countries",
start_date = 2013,
end_date = 2013,
commodity_code = "7308",
frequency = "A"
)
steel_partners23 |> saveRDS("data/tariffs/steel_partners23.RDS")
steel_partners13 |> saveRDS("data/tariffs/steel_partners13.RDS")
steel_partners23 <- readRDS("data/tariffs/steel_partners23.RDS")
steel_partners13 <- readRDS("data/tariffs/steel_partners13.RDS")
steel_partners23 |>
as_tibble() |>
filter(flowDesc == "Import") |>
filter(primaryValue > 10^6) |>
ggplot(aes(x = reorder(partnerDesc, primaryValue), y = primaryValue/10^9, fill = partnerDesc)) +
geom_col() +
coord_flip() +
labs(title = "US Steel Imports 2023",
x = "Partner",
y = "Value (billion USD)",
color = "Partner") +
scale_y_continuous(labels = scales::dollar) +
theme(legend.position = "none")
steel_partners13 |>
as_tibble() |>
filter(flowDesc == "Import") |>
filter(primaryValue > 10^6) |>
ggplot(aes(x = reorder(partnerDesc, primaryValue), y = primaryValue/10^9, fill = partnerDesc)) +
geom_col() +
coord_flip() +
labs(title = "US Steel Imports 2013",
x = "Partner",
y = "Value (billion USD)",
color = "Partner") +
scale_y_continuous(labels = scales::dollar) +
theme(legend.position = "none")
comtradr::ct_get_ref_table('HS') |>
as_tibble() |>
filter(str_detect(text, "Steel|steel"),
str_length(id) == 4)
steel_world <- data.frame()
for (year in 2013:2023) {
cat(year, "\n")
temp <- comtradr::ct_get_data(
reporter = 'USA',
# partner = 'ALL',
start_date = year,
end_date = year,
commodity_code = '7308',
frequency = "M"
)
steel_world <- bind_rows(steel_world, temp)
}
steel_chn <- data.frame()
for (year in 2013:2023) {
cat(year, "\n")
temp <- comtradr::ct_get_data(
reporter = 'USA',
partner = 'CHN',
start_date = year,
end_date = year,
commodity_code = '7308',
frequency = "M"
)
steel_chn <- bind_rows(steel_chn, temp)
}
steel_deu <- data.frame()
for (year in 2013:2023) {
cat(year, "\n")
temp <- comtradr::ct_get_data(
reporter = 'USA',
partner = 'DEU',
start_date = year,
end_date = year,
commodity_code = '7308',
frequency = "M"
)
steel_deu <- bind_rows(steel_deu, temp)
}
steel_world |> saveRDS("data/tariffs/steel_world.RDS")
steel_chn |> saveRDS("data/tariffs/steel_chn.RDS")
steel_deu |> saveRDS("data/tariffs/steel_deu.RDS")
steel_world <- readRDS("data/tariffs/steel_world.RDS")
steel_chn <- readRDS("data/tariffs/steel_chn.RDS")
steel_deu <- readRDS("data/tariffs/steel_deu.RDS")
bind_rows(steel_world |> select(refPeriodId, primaryValue, partnerDesc, flowDesc),
steel_chn |> select(refPeriodId, primaryValue, partnerDesc, flowDesc),
steel_deu |> select(refPeriodId, primaryValue, partnerDesc, flowDesc)) |>
mutate(date = ymd(refPeriodId)) |>
pivot_wider(names_from = partnerDesc, values_from = primaryValue) |>
mutate_all(replace_na, 0) |>
mutate(Others = World - China - Germany) |>
select(-World) |>
pivot_longer(cols = c(China, Germany, Others), names_to = "Partner", values_to = "Value") |>
mutate(flowDesc = ifelse(flowDesc == "Re-export", "Export", flowDesc)) |>
group_by(date, Partner, flowDesc) |>
summarise(Value = sum(Value)) |>
ggplot(aes(x = date, y = Value/10^6, fill = Partner)) +
geom_area() +
labs(title = "US Trade in Steel",
x = "Year",
y = "Value (million USD)",
color = "Flow") +
scale_y_continuous(labels = scales::dollar) +
scale_x_date(date_breaks = "1 year", date_labels = "%Y") +
theme(legend.position = "bottom") +
facet_wrap(~flowDesc)
bind_rows(steel_world |> select(refPeriodId, primaryValue, partnerDesc, flowDesc),
steel_chn |> select(refPeriodId, primaryValue, partnerDesc, flowDesc),
steel_deu |> select(refPeriodId, primaryValue, partnerDesc, flowDesc)) |>
mutate(date = ymd(refPeriodId)) |>
pivot_wider(names_from = partnerDesc, values_from = primaryValue) |>
mutate_all(replace_na, 0) |>
mutate(percChina = China/World) |>
filter(flowDesc == "Import") |>
ggplot(aes(x = date, y = percChina)) +
geom_line() +
labs(title = "US Steel Imports from China",
x = "Year",
y = "Share of total imports",
color = "Partner") +
scale_y_continuous(labels = scales::percent) +
scale_x_date(date_breaks = "1 year", date_labels = "%Y") +
theme(legend.position = "none")
This last chart shows that the share of US steel imports from China has been decreasing since 2018.