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

Background

Trump imposed tariffs on a variety of goods. I asked perplexity.ai to list some:


Solar Panels and Washing Machines

On January 22, 2018, Trump announced tariffs on: - Solar panels (30%) - Washing machines (20-50%)[1][3]

Steel and Aluminum

On March 1, 2018, Trump imposed tariffs on: - Steel (25%) - Aluminum (10%) These tariffs applied to most countries, covering an estimated 4.1% of U.S. imports[1].

Chinese Goods

Trump imposed several rounds of tariffs on Chinese imports:

July 6, 2018: 25% tariff on $34 billion worth of Chinese goods[1][4]

August 23, 2018: 25% tariff on additional $16 billion worth of Chinese goods[1]

September 24, 2018: 10% tariff on $200 billion worth of Chinese goods[2]

May 10, 2019: Increased the September 2018 tariffs from 10% to 25%[2]

September 1, 2019: 15% tariff on $112 billion worth of Chinese goods (known as “List 4a”)[2]

European Union, Canada, and Mexico

In June 2018, Trump extended the steel and aluminum tariffs to the European Union, Canada, and Mexico[1].

These tariffs significantly impacted trade relations and led to retaliatory measures from affected countries. By January 2020, the Trump administration had imposed tariffs on 16.8% of all goods imported into the U.S., measured as a share of the value of all U.S. imports in 2017[1].

Citations: [1] https://en.wikipedia.org/wiki/Trump_tariffs [2] https://taxfoundation.org/research/all/federal/trump-tariffs-biden-tariffs/ [3] https://www.cnn.com/2024/09/24/politics/trump-us-business-tariffs-taxes/index.html [4] https://en.wikipedia.org/wiki/China%E2%80%93United_States_trade_war [5] https://www.piie.com/blogs/trade-and-investment-policy-watch/2018/trumps-trade-war-timeline-date-guide [6] https://www.piie.com/blogs/realtime-economics/2024/trumps-tariff-threats-amount-game-chicken-trading-partners [7] https://www.reuters.com/markets/us/tariffs-tax-cuts-core-trumps-economic-pitch-voters-2024-09-24/ [8] https://www.forbes.com/sites/williampesek/2024/02/23/trumps-60-plan-to-shock-china-will-make-everyone-poorer/


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

Data

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.

Washing Machines

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


Antidumping Duties

In 2016, the US Department of Commerce imposed antidumping duties on washing machines from China. This action was taken in response to a petition filed by Whirlpool Corporation, alleging that Chinese manufacturers were selling washing machines in the US market at unfairly low prices.

Solar Panels

Washing Machines

# 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

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.