This project is part of Clio Wired 3: Programming for Historians at George Mason University. It explores the kinship relations of the Mount Vernon enslaved community from 1786-1799 using network analysis in R. Currently, there is great interest in studying the enslaved community on George Washington’s estate, such as archaeology of the slave cemetery, the physical spaces in which the slaves lived, their labor, free time, and Washington’s role as a slave owner.[1] The Mount Vernon Historic Preservation and Collections department is currently building a slavery database, in which every mention of every slave that lived, worked, or had some part at Mount Vernon is entered. The documents include farm reports, wills, letters, diaries, censuses, etc. In order to track all of the unique people, they generated a spreadsheet compiling every census taken of the slaves.[2]

The census is relatively complete, with farm location, estimated age, skill, spouses, and mothers. This project draws from that data in order to explore the kinship relations from the two most complete censuses: 1786 and 1799. We can parse out parent and child, sibling, and spousal relationships. This project examines the network of known kinship relationships on the estate, the overall structure of the enslaved community, and how it changes in those thirteen years. This project uses the R programming language and network analysis through the igraph package to visualize these hundreds of kinship relationships and place them within space and time. Hopefully, a better and more complete picture of the Mount Vernon enslaved community will arise, as well as a list of new research questions to pursue.

In the historiography of eighteenth-century slavery, a few studies of kinship structures on Chesapeake plantations exist. Herbert G. Gutman explores more the nineteenth-century family structure on plantations in The Black Family in Slavey and Freedom, 1750-1925.[3] In his monograph, Slave Counterpoint: Black Culture in the Eighteenth-Century Chesapeake & Lowcountry, Philip D. Morgan argues that the number of slave kinship ties increased and grew more stable throughout the eighteenth-century. He and Gutman measured this stability mainly by the number of two-parent slave households and single slaves. Two-parent families dominated and single slaves decreased.[4] Mobility also affected this stabilization, as those slaves not moving long distances experienced more stable, local kinship ties. This family stability varies according to plantation size and the owner’s views on slavery, of course, but Morgan states that larger plantations experienced more stable relationships by the late eighteenth-century, especially if the owner no longer sold or bought any slaves, thereby not disrupting families.[5]

These slave kinship relations are difficult to study, because the source base is so minimal. If plantation censuses do exist, they are usually fragmentary. Because Washington kept a relatively complete record of his slaves’ information, we can learn quite a bit from studying the kinship network and community structure of the Mount Vernon slaves with R.

A note on definitions/ terms: Slaves could not legally marry.[6] A “husband” or “wife” listed on the census does not necessarily mean the same thing as a legal marriage, nor does it imply behaviors associated with legal marriage. A structure of two parents or a single parent with children does not necessarily constitute a traditional family, as perceived by a slave. Additionally, polygyny and polyandry were common.[7] We cannot assume blood relations or a slave’s perspective when no direct sources exist. However, in order to analyze the community, I have decided to call the ties “kinship or familial relationships” that make up “family structures”.

Network Analysis

First, we load the necessary libraries.


Data Manipulation

I cleaned the data from the compiled census with Open Refine in order to make it amenable to computation.[8] If differing birth years existed, I chose the 1799 year. I created a new row or observation for each slave on each census, including any changes in skill or farm. Additionally, I only included those slaves known for certain on the two censuses.

Read in the Data

The data for this project exists in three csv files. The first file contains every slave with at least one kinship relation on Mount Vernon, from 1786-1799 .

slaverel <- read.csv("~//Desktop/Clio-3/finalproject/slaveRelationships.csv", stringsAsFactors = FALSE)
##        id       id.1 relationship
## 1 Abbay A  Barbary A      Sibling
## 2 Abbay A   George C      Sibling
## 3 Abbay A   Hannah A      Sibling
## 4 Abbay A    Jesse B      Sibling
## 5 Abbay A     Kate D      Sibling
## 6 Abbay A Lawrence B      Sibling

The second contains every slave and the respective static information, such as gender and owner, for 1786 and 1799.

total_slave <- read.csv("~//Desktop/Clio-3/finalproject/clean.csv", stringsAsFactors = FALSE) %>%
  select(id, Gender, Birth.Year, Owner)
##        id Gender Birth.Year             Owner
## 1 Abbay A Female       1789     Custis Estate
## 2 Abram A   Male         NA   Penelope French
## 3  Adam A   Male       1792 George Washington
## 4 Agnes A Female       1763     Custis Estate
## 5 Agnes B Female       1774 George Washington
## 6  Alce A Female       1791 George Washington

The third file contains both the 1786 and 1799 censuses with the relevant slaves. This means the slaves present in both censuses are repeated but might have a different skill or farm.

slave_census <- read.csv("~//Desktop/Clio-3/finalproject/census.csv", stringsAsFactors = FALSE) %>%
  select(id, Gender, Birth.Year, Skill, Farm, Census, Owner)
##        id Gender Birth.Year                  Skill       Farm Census
## 1 Abbay A Female       1789                  Child  Dogue Run   1799
## 2 Abram A   Male         NA Cultivator of the Soil Union Farm   1799
## 3  Adam A   Male       1792                  Child Muddy Hole   1799
## 4  Adam B   Male         NA Cultivator of the Soil River Farm   1786
## 5  Adam C   Male         NA Cultivator of the Soil  Dogue Run   1786
## 6 Agnes A Female       1763 Cultivator of the Soil River Farm   1786
##               Owner
## 1     Custis Estate
## 2   Penelope French
## 3 George Washington
## 4 George Washington
## 5 George Washington
## 6     Custis Estate

Joining the Data

Next, we must separate out the two most important and complete censuses: 1786 and 1799. We use the dplyr package to filter out the census year and to select only the variables that change between the two censuses.

slave_1786 <- slave_census %>%
  filter(Census == "1786") %>%
  select(id, Census, Skill, Farm)

slave_1799 <- slave_census %>%
  filter(Census == "1799") %>%
  select(id, Census, Skill, Farm)

We can join the two censuses into one dataframe by the “id” variable (column name) in order to access that information on the network graph.

total_slave <- total_slave %>%
  left_join(slave_1786, by = "id") %>%
  left_join(slave_1799, by = "id")
##        id Gender Birth.Year             Owner Census.x
## 1 Abbay A Female       1789     Custis Estate       NA
## 2 Abram A   Male         NA   Penelope French       NA
## 3  Adam A   Male       1792 George Washington       NA
## 4 Agnes A Female       1763     Custis Estate     1786
## 5 Agnes B Female       1774 George Washington     1786
## 6  Alce A Female       1791 George Washington       NA
##                  Skill.x     Farm.x Census.y                Skill.y
## 1                   <NA>       <NA>     1799                  Child
## 2                   <NA>       <NA>     1799 Cultivator of the Soil
## 3                   <NA>       <NA>     1799                  Child
## 4 Cultivator of the Soil River Farm     1799 Cultivator of the Soil
## 5                  Child  Dogue Run     1799 Cultivator of the Soil
## 6                   <NA>       <NA>     1799                  Child
##       Farm.y
## 1  Dogue Run
## 2 Union Farm
## 3 Muddy Hole
## 4 River Farm
## 5  Dogue Run
## 6 Muddy Hole

Create a Graph Object

We create a graph object of the slave relationships dataframe (slaverel) in order to graph the kinship relations between the slaves. Since this is a kinship network graph, it is undirected.

slave_graph <-, directed = "FALSE")

In order to add those slaves without kinship relations, we must add them as extra vertices to the graph object.

slave_graph <- slave_graph + vertex("Adam B", "Adam C", "Anthony A", "Austin A", "Bath A", "Bristol A", "Brunswick A", "Caesar A", "Cloe A", "Cupid A", "Daniel A", "Daphne D", "Doll A", "Doll E", "Essex A", "Frank B", "Giles A", "Hannah E", "Hercules A", "Isaac B", "Jack B", "Jack G", "Jack H", "Jack I", "James D", "Jenny B", "Jenny E", "Joe E", "Juba A", "Julius A", "London A", "Marcus A", "Matt A", "Milly C", "Moll A", "Molly A", "Morris B", "Moses C", "Murria A", "Nancy I", "Paris A", "Paul A", "Peter C", "Robin A", "Robin B", "Schomberg A", "Spencer A", "Sue A", "Tom D", "William Lee", "Will D", "Will F", "Will H")

Now, we create another dataframe that lists all the vertex attributes for each slave in order to visualize them on the network graph.

slave_vertex <- data_frame(name = V(slave_graph)$name) %>%
  left_join(total_slave, by = c("name" = "id"))
## Source: local data frame [6 x 10]
##      name Gender Birth.Year             Owner Census.x
## 1 Abbay A Female       1789     Custis Estate       NA
## 2 Abram A   Male         NA   Penelope French       NA
## 3  Adam A   Male       1792 George Washington       NA
## 4 Agnes A Female       1763     Custis Estate     1786
## 5 Agnes B Female       1774 George Washington     1786
## 6  Alce A Female       1791 George Washington       NA
## Variables not shown: Skill.x (chr), Farm.x (chr), Census.y (int), Skill.y
##   (chr), Farm.y (chr)

Plotting the First Network Graph

In order to create a more discernible network graph, set the vertex size to 3 and remove the vertex labels in the plot function. The set.seed function keeps the graph in the same position, so it does not rotate every time the graph is plotted.

plot(slave_graph, vertex.label = NA)
title("Slave Family Structures on Mount Vernon, 1786 - 1799")

plot of chunk unnamed-chunk-10

Immediately, the overall kinship structure of the enslaved community is apparent. It seems that three family structures comprise one large family structure and several smaller structures exist, as well. Many slaves experienced no kinship relations (no known kinship relations) and some slaves were only connected to one or two other people. This graph provides a lot of information, but in order to analyze it further, we must be able to visualize the vertex attributes and the different kinship relationships.

Visualizing Gender

In order to visualize the gender of the slaves, we can change the shape of each vertex accordingly. We use a simple ifelse function to iterate over the Gender attribute in the slave_vertex dataframe and assign circles or squares to the respective gender. The rectangle shape is added in case any gender is not listed as male or female, ie missing.

V(slave_graph)$shape <- ifelse(slave_vertex$Gender == "Female", "circle", 
                               ifelse(slave_vertex$Gender == "Male", "square", 
plot(slave_graph, vertex.label = NA)
title("Visualizing Gender")

plot of chunk unnamed-chunk-11

This graph is more helpful, as it allows us to begin thinking about gender ratios on the farms. However, the edges between them are not meaningful unless we can visualize them.


In order to visualize the different kinships relations, we can colorize the edges according to type of relation with a function. We can adapt the lookup function for vertex attributes created by Lincoln Mullen to edge attributes. [9] It returns a color based on the relationship.

lookup_edge <- function(relationship) {
  if(relationship == "Spouse") return("red")
  if(relationship == "Child") return("orange")
  if(relationship == "Sibling") return("blue")

lookup_edge <- Vectorize(lookup_edge, USE.NAMES = FALSE)

E(slave_graph)$color <- lookup_edge(E(slave_graph)$relationship)
     vertex.label = NA,      
     vertex.size = 3)
title("Visualizing Kinship Relations")
legend("bottomleft", legend = c("Spouse", "Child", "Sibling"),
       col = c("red", "orange", "blue"), pch = 19,   
               title = "Kinship Relation")