Part 1: Data Loading and Cleaning

Clean the Data

Rename columns and change data type for both datasets

# Process Trans-Atlantic Data
trans_clean <- trans %>%
  # Rename the columns for readability
  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
  ) %>%
  # Convert year to integer and slave numbers to numeric
  mutate(
    year = as.integer(year),
    slaves_embarked = as.numeric(slaves_embarked),
    slaves_disembarked = as.numeric(slaves_disembarked)
  )


# Process Intra-American Data
intra_clean <- 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 the Data

Identify successful outcomes, filter the data, and add useful columns

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"
)


# Filter Trans-Atlantic data
trans_filtered <- trans_clean %>%
  filter(
    !is.na(slaves_disembarked),
    slaves_disembarked > 0,
    particular_outcome %in% successful_outcomes
  ) %>%
  # Add useful columns
  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"
  )

# Filter Intra-American data
intra_filtered <- intra_clean %>%
  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 both datasets

combined <- bind_rows(trans_filtered, intra_filtered)

Part 2: Analysis and Questions

1. Total Slaves Imported to the US

Find the gross slaves imported

gross_us <- combined %>%
  filter(is_us == TRUE) %>%
  summarise(gross_us = sum(slaves_disembarked, na.rm = TRUE)) %>%
  pull(gross_us)
## Gross slaves imported to the US: 395919

Find how many were re-exported

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)
## Slaves re-exported from the US: 7652

Total slaves imported to the US

net_us <- gross_us - re_exports
## Net slaves retained in the US: 388267

2. Proportion of all slaves taken from Africa

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

proportion <- net_us / trans_total_embarked
## Proportion of all slaves taken from Africa (net US): 0.05107614

3. Graph slave imports by decade to the US

# Summarize by decade
us_imports_decade <- combined %>%
  filter(is_us == TRUE) %>%
  group_by(decade) %>%
  summarise(total_imported = sum(slaves_disembarked, na.rm = TRUE)) %>%
  arrange(decade)

# Plot as bar graph
ggplot(us_imports_decade, aes(x = factor(decade), y = total_imported)) +
  geom_bar(stat = "identity", fill = "steelblue") +
  labs(
    title = "Slave Imports to the US by Decade",
    x = "Decade",
    y = "Total Slaves Disembarked"
  ) +
  theme_minimal() + 
  theme(
    axis.text.x = element_text(size = 7)  # smaller font size
  )

4. Imports to the US by decade and region/port/state

Filter for US, group by decade, region and port

combined_us_states <- 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("Norfolk|Richmond|Hampton", dis_port, ignore.case = TRUE) ~ "Virginia",
      grepl("Baltimore", dis_port, ignore.case = TRUE) ~ "Maryland",
      grepl("Philadelphia", dis_port, ignore.case = TRUE) ~ "Pennsylvania",
      grepl("New York", dis_port, ignore.case = TRUE) ~ "New York",
      grepl("Boston", dis_port, ignore.case = TRUE) ~ "Massachusetts",
      TRUE ~ "Other/Unknown"
    )
  ) %>%
  group_by(decade, state, dis_broad, dis_port) %>%
  summarise(total_imported = sum(slaves_disembarked, na.rm = TRUE), .groups = "drop")
## # A tibble: 272 × 5
##    decade state         dis_broad              dis_port           total_imported
##     <dbl> <chr>         <chr>                  <chr>                       <dbl>
##  1   1610 Virginia      Mainland North America Hampton                        29
##  2   1620 Other/Unknown Mainland North America Virginia, port un…              3
##  3   1630 Massachusetts Mainland North America Boston                          7
##  4   1630 New York      Mainland North America New York                       53
##  5   1630 Other/Unknown Mainland North America Virginia, port un…             13
##  6   1640 New York      Mainland North America New York                       69
##  7   1640 Other/Unknown Mainland North America Virginia, port un…             12
##  8   1650 New York      Mainland North America New York                      477
##  9   1650 Other/Unknown Mainland North America Maryland, port un…              5
## 10   1650 Other/Unknown Mainland North America Virginia, port un…            125
## # ℹ 262 more rows

Plot the imports by decade, region, port, and state

ggplot(combined_us_states, aes(x = factor(decade), y = total_imported, fill = state)) +
  geom_col() +
  facet_wrap(~ state, scales = "free_y") +
  labs(
    title = "Slave Imports to the U.S. by Decade and State",
    x = "Decade",
    y = "Slaves Disembarked",
    fill = "State"
  ) +
  theme_minimal() +
  theme(
    axis.text.x = element_text(size = 5, angle = 75, hjust = 1),
    legend.position = "none",
    strip.text = element_text(face = "bold")
  )

Countries participating in export from Africa, by decade

exports_by_country <- trans_filtered %>%
  mutate(
    country = voyage_ship__imputed_nationality__name
  ) %>%
  filter(country > 0) %>%
  filter(!is.na(decade)) %>%
  group_by(decade, country) %>%
  summarise(total_embarked = sum(slaves_embarked, na.rm = TRUE), .groups = "drop")
## # A tibble: 167 × 3
##    decade country           total_embarked
##     <dbl> <chr>                      <dbl>
##  1   1510 Spain / Uruguay              144
##  2   1520 Spain / Uruguay             1043
##  3   1530 Portugal / Brazil            560
##  4   1530 Spain / Uruguay              224
##  5   1540 Portugal / Brazil            160
##  6   1550 Portugal / Brazil            718
##  7   1560 Great Britain               1749
##  8   1560 Portugal / Brazil            176
##  9   1560 Spain                        400
## 10   1560 Spain / Uruguay              208
## # ℹ 157 more rows
ggplot(exports_by_country, aes(x = factor(decade), y = total_embarked, fill = country)) +
  geom_col(position = "dodge") +
  labs(
    title = "African Slave Exports by Country and Decade",
    x = "Decade",
    y = "Slaves Embarked",
    fill = "Exporting Country"
  ) +
  theme_minimal() +
  theme(
    axis.text.x = element_text(size = 8, angle = 45, hjust = 1),
    legend.position = "bottom"
  )

Part 3: Summary

This analysis combines Trans-Atlantic and Intra-American slave trade data to examine the flow of enslaved people to the United States. 388,267 individuals were imported, accounting for about 5.1% of the total transatlantic trade. Imports peaked in the late early 1800s before starting to decline in the 1820s, with Louisiana and South Carolina being the highest importing states. Britain, Portugal, and Spain were the highest exporting nations overall.