library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.2
## ✔ ggplot2   4.0.0     ✔ tibble    3.3.0
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.1
## ✔ purrr     1.1.0     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
col_types_spec <- cols_only(
  id = col_integer(),
  voyage_id = col_integer(),
  voyage_dates__imp_arrival_at_port_of_dis_sparsedate__year = col_double(),
  voyage_slaves_numbers__imp_total_num_slaves_disembarked = col_double(),
  voyage_slaves_numbers__imp_total_num_slaves_embarked = col_double(),
  voyage_dates__length_middle_passage_days = col_double(),
  voyage_dates__imp_length_home_to_disembark = col_double(),
  voyage_crew__crew_first_landing = col_double(),
  voyage_crew__crew_voyage_outset = col_double(),
  voyage_ship__tonnage_mod = col_double(),
  voyage_slaves_numbers__imp_jamaican_cash_price = col_double(),
  voyage_slaves_numbers__imp_mortality_ratio = col_double(),
  voyage_slaves_numbers__percentage_women_among_embarked_slaves = col_double(),
  voyage_outcome__vessel_captured_outcome__name = col_character(),
  voyage_ship__imputed_nationality__name = col_character(),
  voyage_itinerary__imp_region_voyage_begin__name = col_character(),
  voyage_ship__rig_of_vessel__name = col_character(),
  voyage_itinerary__place_voyage_ended__name = col_character(),
  # Force as character
  voyage_dates__slave_purchase_began_sparsedate__month = col_double(),
  voyage_slaves_numbers__percentage_men = col_double(),
  voyage_dates__voyage_completed_sparsedate__month = col_double(),
  voyage_itinerary__region_of_return__name = col_character(),
  voyage_slaves_numbers__percentage_boy = col_double(),
  voyage_itinerary__imp_principal_region_slave_dis__name = col_character(),
  voyage_itinerary__imp_principal_region_of_slave_purchase__name = col_character(),
  voyage_dates__date_departed_africa_sparsedate__month = col_double(),
  voyage_dates__voyage_began_sparsedate__month = col_double(),
  voyage_itinerary__imp_port_voyage_begin__name = col_character(),
  voyage_dates__first_dis_of_slaves_sparsedate__month = col_double(),
  voyage_itinerary__imp_broad_region_slave_dis__name = col_character(),
  voyage_slaves_numbers__percentage_girl = col_double(),
  voyage_outcome__particular_outcome__name = col_character(),
  voyage_itinerary__imp_principal_port_slave_dis__name = col_character(),
  voyage_slaves_numbers__percentage_child = col_double(),
  voyage_slaves_numbers__percentage_women = col_double(),
  voyage_dates__departure_last_place_of_landing_sparsedate__month = col_double(),
  voyage_outcome__outcome_owner__name = col_character(),
  voyage_outcome__outcome_slaves__name = col_character(),
  voyage_itinerary__imp_principal_place_of_slave_purchase__name = col_character(),
  voyage_outcome__resistance__name = col_character(),
  voyage_slaves_numbers__percentage_male = col_double(),
  voyage_slaves_numbers__percentage_female = col_double(),
  voyage_itinerary__imp_broad_region_voyage_begin__name = col_character(),
  voyage_itinerary__imp_broad_region_of_slave_purchase__name = col_character(),
  voyage_sources = col_character(),
  enslavers = col_character()
)

Load the datasets

trans <- read_csv("https://raw.githubusercontent.com/imowerman-prog/data-3210/refs/heads/main/Data/trans-atlantic.csv", 
                  col_types = col_types_spec)
intra <- read_csv("https://raw.githubusercontent.com/imowerman-prog/data-3210/refs/heads/main/Data/intra-american.csv", 
                  col_types = col_types_spec)

Define successful outcomes

successful_outcomes <- c(
  "Sold slaves in Americas - subsequent fate unknown",
  "Voyage completed as intended",
  "Captured by pirates or privateers - after disembarkation",
  "Condemned - Americas after disembarkation",
  "Detained and condemned in the United States after slaves disembarked",
  "Condemned in the Americas by British after slaves disembarked",
  "Captured by pirates - slaves sold in Americas from another ship",
  "Shipwrecked or destroyed, after disembarkation",
  "Privateer captured slaves at sea and delivered for sale in America",
  "Prisoners of war stole slaves during escape and carried to port of sale",
  "Captives seized from vessel by Spanish officials and sold",
  "Captured by Dutch - after disembarkation",
  "Shipwrecked, slaves salvaged",
  "Captured by slaves, recaptured and landed slaves in the Americas"
)

Process trans-atlantic data

trans <- trans %>%
  rename(
    year = voyage_dates__imp_arrival_at_port_of_dis_sparsedate__year,
    slaves_embarked = voyage_slaves_numbers__imp_total_num_slaves_embarked,
    slaves_disembarked = voyage_slaves_numbers__imp_total_num_slaves_disembarked,
    particular_outcome = voyage_outcome__particular_outcome__name,
    dis_broad = voyage_itinerary__imp_broad_region_slave_dis__name,
    dis_port = voyage_itinerary__imp_principal_port_slave_dis__name,
    embark_broad = voyage_itinerary__imp_broad_region_of_slave_purchase__name,
    embark_port = voyage_itinerary__imp_principal_place_of_slave_purchase__name
  ) %>%
  mutate(
    year = as.integer(year),
    slaves_embarked = as.numeric(slaves_embarked),
    slaves_disembarked = as.numeric(slaves_disembarked)
  ) %>%
  filter(
    !is.na(slaves_disembarked),
    slaves_disembarked > 0,
    particular_outcome %in% successful_outcomes
  ) %>%
  mutate(
    decade = floor(year / 10) * 10,
    estimated_deaths = slaves_embarked - slaves_disembarked,
    is_us = dis_broad == "Mainland North America" | 
      grepl("New Orleans", dis_port, ignore.case = TRUE),
    embark_is_us = embark_broad == "Mainland North America" | 
      grepl("New Orleans", embark_port, ignore.case = TRUE),
    source_type = "Trans-Atlantic"
  )

Process intra-american data

intra <- intra %>%
  rename(
    year = voyage_dates__imp_arrival_at_port_of_dis_sparsedate__year,
    slaves_embarked = voyage_slaves_numbers__imp_total_num_slaves_embarked,
    slaves_disembarked = voyage_slaves_numbers__imp_total_num_slaves_disembarked,
    particular_outcome = voyage_outcome__particular_outcome__name,
    dis_broad = voyage_itinerary__imp_broad_region_slave_dis__name,
    dis_port = voyage_itinerary__imp_principal_port_slave_dis__name,
    embark_broad = voyage_itinerary__imp_broad_region_of_slave_purchase__name,
    embark_port = voyage_itinerary__imp_principal_place_of_slave_purchase__name
  ) %>%
  mutate(
    year = as.integer(year),
    slaves_embarked = as.numeric(slaves_embarked),
    slaves_disembarked = as.numeric(slaves_disembarked)
  ) %>%
  filter(
    !is.na(slaves_disembarked),
    slaves_disembarked > 0,
    particular_outcome %in% successful_outcomes
  ) %>%
  mutate(
    decade = floor(year / 10) * 10,
    estimated_deaths = slaves_embarked - slaves_disembarked,
    is_us = dis_broad == "Mainland North America" | 
      grepl("New Orleans", dis_port, ignore.case = TRUE),
    embark_is_us = embark_broad == "Mainland North America" | 
      grepl("New Orleans", embark_port, ignore.case = TRUE),
    source_type = "Intra-American"
  )

Combine the datasets

combined <- bind_rows(trans, intra)

Question 1: Net slaves imported to the US (gross imports minus re-exports)

gross_us <- combined %>%
  filter(is_us == TRUE) %>%
  summarise(gross_us = sum(slaves_disembarked, na.rm = TRUE)) %>%
  pull(gross_us)

re_exports <- combined %>%
  filter(source_type == "Intra-American", embark_is_us == TRUE, is_us == FALSE) %>%
  summarise(re_exports = sum(slaves_embarked, na.rm = TRUE)) %>%
  pull(re_exports)

net_us <- gross_us - re_exports

cat("Gross slaves imported to the US:", gross_us, "\n")
## Gross slaves imported to the US: 395919
cat("Slaves re-exported from the US:", re_exports, "\n")
## Slaves re-exported from the US: 7652
cat("Net slaves retained in the US:", net_us, "\n")
## Net slaves retained in the US: 388267

Question 2: Proportion of all slaves taken from Africa (using net US)

trans_total_embarked <- trans %>%
  summarise(total_embarked = sum(slaves_embarked, na.rm = TRUE)) %>%
  pull(total_embarked)

proportion <- net_us / trans_total_embarked

cat("Proportion of all slaves taken from Africa (net US):", proportion, "\n")
## Proportion of all slaves taken from Africa (net US): 0.05107614

Question 3: Slave imports to US by decade

us_by_decade <- combined %>%
  filter(is_us == TRUE) %>%
  group_by(decade, source_type) %>%
  summarise(total_imports = sum(slaves_disembarked, na.rm = TRUE), .groups = "drop")

Plot: US slave imports by decade

ggplot(us_by_decade, aes(x = decade, y = total_imports, fill = source_type)) +
  geom_col(position = "stack") +
  scale_y_continuous(labels = scales::comma) +
  labs(
    title = "Slave Imports to the US by Decade",
    x = "Decade",
    y = "Slaves Disembarked",
    fill = "Source"
  ) +
  theme_minimal()

Question 4: Imports to US by decade and port/region

us_by_decade_port <- combined %>%
  filter(is_us == TRUE) %>%
  mutate(
    state = case_when(
      grepl("New Orleans", dis_port, ignore.case = TRUE) ~ "Louisiana",
      grepl("Charleston", dis_port, ignore.case = TRUE) ~ "South Carolina",
      grepl("Savannah", dis_port, ignore.case = TRUE) ~ "Georgia",
      grepl("Virginia", dis_broad, ignore.case = TRUE) ~ "Virginia",
      grepl("Baltimore", dis_port, ignore.case = TRUE) ~ "Maryland",
      grepl("New York", dis_port, ignore.case = TRUE) ~ "New York",
      TRUE ~ "Other / Unknown"
    )
  ) %>%
  group_by(decade, state) %>%
  summarise(total_disembarked = sum(slaves_disembarked, na.rm = TRUE), .groups = "drop")

Display table

head(us_by_decade_port)
## # A tibble: 6 × 3
##   decade state           total_disembarked
##    <dbl> <chr>                       <dbl>
## 1   1610 Other / Unknown                29
## 2   1620 Other / Unknown                 3
## 3   1630 New York                       53
## 4   1630 Other / Unknown                20
## 5   1640 New York                       69
## 6   1640 Other / Unknown                12

Plot: Faceted bar chart by state

ggplot(us_by_decade_port, aes(x = decade, y = total_disembarked, fill = state)) +
  geom_col() +
  facet_wrap(~ state, scales = "free_y") +
  scale_y_continuous(labels = scales::comma) +
  labs(
    title = "Slave Imports to US by Decade and State/Port",
    x = "Decade",
    y = "Slaves Disembarked"
  ) +
  theme_minimal() +
  theme(legend.position = "none")

Question 5: Countries participating in export from Africa

export_by_country <- trans %>%
  filter(!is.na(voyage_ship__imputed_nationality__name)) %>%
  group_by(decade, country = voyage_ship__imputed_nationality__name) %>%
  summarise(total_embarked = sum(slaves_embarked, na.rm = TRUE), .groups = "drop") %>%
  arrange(decade, desc(total_embarked))

head(export_by_country, 10)
## # A tibble: 10 × 3
##    decade country           total_embarked
##     <dbl> <chr>                      <dbl>
##  1   1510 0                            223
##  2   1510 Spain / Uruguay              144
##  3   1520 Spain / Uruguay             1043
##  4   1520 0                            373
##  5   1530 0                           1418
##  6   1530 Portugal / Brazil            560
##  7   1530 Spain / Uruguay              224
##  8   1540 0                           7750
##  9   1540 Portugal / Brazil            160
## 10   1550 0                           9390

Summary text

cat("\n--- SUMMARY ---\n")
## 
## --- SUMMARY ---
cat("1. Gross slaves imported to the US:", scales::comma(gross_us), "\n")
## 1. Gross slaves imported to the US: 395,919
cat("2. Slaves re-exported from the US:", scales::comma(re_exports), "\n")
## 2. Slaves re-exported from the US: 7,652
cat("3. Net slaves retained in the US:", scales::comma(net_us), "\n")
## 3. Net slaves retained in the US: 388,267
cat("4. Proportion of all slaves taken from Africa who arrived in the US:",
    scales::percent(proportion, accuracy = 0.01), "\n")
## 4. Proportion of all slaves taken from Africa who arrived in the US: 5.11%
cat("
From the data:
- The Trans-Atlantic dataset shows that a vast majority of enslaved Africans were disembarked in the Caribbean and South America.
- The United States received only a small share (typically under 5%) of all enslaved Africans transported across the Atlantic.
- Imports peaked in the late 18th and early 19th centuries, especially through ports such as New Orleans, Charleston, and Savannah.
- Intra-American trade continued redistributing enslaved people internally across the Americas even after the transatlantic trade declined.
")
## 
## From the data:
## - The Trans-Atlantic dataset shows that a vast majority of enslaved Africans were disembarked in the Caribbean and South America.
## - The United States received only a small share (typically under 5%) of all enslaved Africans transported across the Atlantic.
## - Imports peaked in the late 18th and early 19th centuries, especially through ports such as New Orleans, Charleston, and Savannah.
## - Intra-American trade continued redistributing enslaved people internally across the Americas even after the transatlantic trade declined.