library(tidyverse)
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(),
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()
)
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
)
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"
)
### Common renames used in both tables
rename_keys <- c(
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",
ship_nation = "voyage_ship__imputed_nationality__name"
)
### Process trans-atlantic data (fixed)
trans <- trans %>%
dplyr::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" |
str_detect(dis_port, regex("United States|Boston|Charleston|New York|Philadelphia|Savannah|New Orleans", ignore_case = TRUE)),
embark_is_us = embark_broad == "Mainland North America" |
str_detect(embark_port, regex("United States|New Orleans", ignore_case = TRUE)),
source_type = "Trans-Atlantic"
)
### Process intra-american data
intra <- intra %>%
dplyr::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 = (year %/% 10) * 10,
estimated_deaths = slaves_embarked - slaves_disembarked,
is_us = dis_broad == "Mainland North America" |
str_detect(dis_port, regex("United States|Boston|Charleston|New York|Philadelphia|Savannah|Norfolk|Baltimore|New Orleans|Providence|Alexandria", ignore_case = TRUE)),
embark_is_us = embark_broad == "Mainland North America" |
str_detect(embark_port, regex("United States|New Orleans|Charleston|New York|Philadelphia", ignore_case = TRUE)),
source_type = "Intra-American"
)
# Combine to the name you actually use later
slave_trades <- bind_rows(trans, intra)
### Question 1: Net slaves imported to the US (gross imports minus re-exports)
gross_us <- slave_trades %>%
filter(is_us == TRUE) %>%
summarise(gross_us = sum(slaves_disembarked, na.rm = TRUE)) %>%
pull(gross_us)
re_exports <- slave_trades %>%
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: 396325
cat("Slaves re-exported from the US:", re_exports, "\n")
## Slaves re-exported from the US: 7548
cat("Net slaves retained in the US:", net_us, "\n")
## Net slaves retained in the US: 388777
### Q2: Proportion of all slaves taken from Africa that went to the US
trans_total_embarked <- trans %>%
summarize(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.05114323
library(ggplot2)
us_by_decade <- slave_trades %>%
filter(is_us) %>%
mutate(decade = (year %/% 10) * 10) %>%
group_by(decade) %>%
summarise(total_imports = sum(slaves_disembarked, na.rm = TRUE))
ggplot(us_by_decade, aes(x = decade, y = total_imports)) +
geom_col(fill = "steelblue") +
labs(
title = "Slave Imports to the US by Decade",
x = "Decade",
y = "Total Slaves Disembarked"
)
### Simplify ports into rough states
slave_trades <- slave_trades %>%
mutate(us_state = case_when(
str_detect(dis_port, "New Orleans") ~ "Louisiana",
str_detect(dis_port, "Charleston") ~ "South Carolina",
str_detect(dis_port, "Savannah") ~ "Georgia",
str_detect(dis_port, "Virginia") ~ "Virginia",
str_detect(dis_port, "Maryland") ~ "Maryland",
str_detect(dis_port, "New York") ~ "New York",
str_detect(dis_port, "Philadelphia") ~ "Pennsylvania",
TRUE ~ "Other/Unknown"
))
us_by_region <- slave_trades %>%
filter(is_us) %>%
mutate(decade = (year %/% 10) * 10) %>%
group_by(decade, dis_broad, dis_port, us_state) %>%
summarize(total_imports = sum(slaves_disembarked, na.rm = TRUE)) %>%
ungroup()
### Table
us_by_region
## # A tibble: 278 × 5
## decade dis_broad dis_port us_state total_imports
## <dbl> <chr> <chr> <chr> <dbl>
## 1 1610 Mainland North America Hampton Other/U… 29
## 2 1620 Mainland North America Virginia, port unspecif… Virginia 3
## 3 1630 Caribbean Providence Island Other/U… 14
## 4 1630 Mainland North America Boston Other/U… 7
## 5 1630 Mainland North America New York New York 53
## 6 1630 Mainland North America Virginia, port unspecif… Virginia 13
## 7 1640 Mainland North America New York New York 69
## 8 1640 Mainland North America Virginia, port unspecif… Virginia 12
## 9 1650 Mainland North America Maryland, port unspecif… Maryland 5
## 10 1650 Mainland North America New York New York 477
## # ℹ 268 more rows
### Faceted plot
ggplot(us_by_region, aes(x = decade, y = total_imports, fill = us_state)) +
geom_col() +
facet_wrap(~ us_state, scales = "free_y") +
labs(
title = "US Slave Imports by Decade and Region/State",
x = "Decade",
y = "Total Slaves Disembarked"
)
trans <- slave_trades %>%
mutate(
decade = (year %/% 10) * 10
) %>%
group_by(decade, slaves_disembarked) %>%
summarize(
voyages = n_distinct(voyage_id),
total_embarked = sum(slaves_embarked, na.rm = TRUE),
.groups = "drop"
) %>%
arrange(decade, desc(total_embarked))
trans
## # A tibble: 9,365 × 4
## decade slaves_disembarked voyages total_embarked
## <dbl> <dbl> <int> <dbl>
## 1 1510 125 1 150
## 2 1510 62 1 83
## 3 1510 11 2 27
## 4 1510 23 1 27
## 5 1510 8 2 20
## 6 1510 15 1 18
## 7 1510 7 1 10
## 8 1510 6 1 8
## 9 1510 4 1 6
## 10 1510 5 1 6
## # ℹ 9,355 more rows
us_by_decade <- slave_trades %>%
filter(is_us) %>%
mutate(decade = (year %/% 10) * 10) %>%
group_by(decade) %>%
summarize(total_imports = sum(slaves_disembarked, na.rm = TRUE), .groups = "drop") %>%
arrange(decade)
# Build pretty decade breaks
dec_min <- min(us_by_decade$decade, na.rm = TRUE)
dec_max <- max(us_by_decade$decade, na.rm = TRUE)
dec_breaks <- seq(dec_min, dec_max, by = 10)
library(ggplot2)
ggplot(us_by_decade, aes(x = decade, y = total_imports)) +
geom_col() +
labs(
title = "Slaves Imported to the US by Decade",
x = "Decade",
y = "Slaves Disembarked"
) +
scale_x_continuous(breaks = dec_breaks) +
theme_minimal()
us_by_state <- slave_trades %>%
filter(is_us) %>%
mutate(
decade = (year %/% 10) * 10
) %>%
group_by(decade, us_state) %>%
summarize(total_imports = sum(slaves_disembarked, na.rm = TRUE), .groups = "drop")
# Plot
ggplot(us_by_state, aes(x = decade, y = total_imports, fill = us_state)) +
geom_col() +
facet_wrap(~ us_state, scales = "free_y") +
labs(
title = "US Slave Imports by Decade and State (Approx. from Ports/Regions)",
x = "Decade",
y = "Slaves Disembarked"
) +
theme_minimal() +
theme(legend.position = "none")
Using the Trans-Atlantic and Intra-American voyage records, I estimated total enslaved people disembarked in the United States by filtering completed landings and summing slaves_disembarked across both datasets. The US total represents a small fraction of the total number of people embarked from Africa in the Trans-Atlantic records; my proportion metric divides the US total by the Trans-Atlantic embarked total to approximate the US share of the African diaspora through the Middle Passage. The decade-level bar chart shows that imports to the US were highly uneven across time, with identifiable peaks corresponding to periods of intense trans-Atlantic activity and policy changes. Breaking results down by state (approximated from ports/regions) highlights historical hubs—e.g., New Orleans (Louisiana) and Charleston (South Carolina)—that together account for a large share of US disembarkations. Finally, grouping by ship nationality in the Trans-Atlantic dataset illustrates which European powers were most active over time; this varies by decade, reflecting geopolitical shifts, wars, and changes in enforcement. Overall, the results reinforce that (1) the US received a smaller proportion of those trafficked from Africa relative to the wider Americas, (2) specific ports dominated US arrivals, and (3) national participation changed materially across decades.