Introduction

In this document I create Dorling cartograms showing changing estimates of public support for marriage equality by state in 1994-1996 (the first years for which I was able to find data), 2004, 2010, 2012, 2014, and 2017.

I also create a similar cartogram showing estimates of public support by state in 2015 for inclusion of transgender individuals in non-discrimination policies.

For those readers unfamiliar with the R statistical software and the additional Tidyverse software I use to manipulate and plot data, I’ve included some additional explanation of various steps. For more information check out the the tutorial “Getting started with the Tidyverse”. For a summary of how to create Dorling cartograms see the article “Hello, Dorling! (Creating Dorling Cartograms from R Spatial Objects)”.

Setup and data preparation

Libraries

I use the tidyverse package of functions for general data manipulation, the albersusa and spdorling packages to get a U.S. map and create Dorling cartograms for it, and the knitr package to produce printed tables. I also use the tools package to get the md5sum function.

library("tidyverse")
library("albersusa")
library("spdorling")
library("knitr")
library("tools")

Note that the albersusa and spdorling packages need to be installed from their respective source repositories on GitHub; this in turn requires that the devtools package be installed.

Building the spdorling package from source requires that the rgeos package be installed, which in turn requires installation of the Ubuntu package libgeos-dev. (I run this analysis using RStudio Server running on Ubuntu Server 18.04 LTS.) Building the albersusa package from source requires that the sf and rgdal packages be installed, which in turn requires installation of the Ubuntu packages libudunits2-dev and libgdal-dev.

Data sources

For 1994-1996 and 2010 I use estimates on changing attitudes relating to marriage equality by state from Jeffrey Lax and Justin Phillips of Columbia University. For 2004, 2012, and 2014 I use similar estimates from Andrew Flores and Scott Barclay of the Williams Institute. For 2017 I use estimates from the American Values Atlas published by the Public Religion Research Institute.

For support of inclusion of transgender individuals in non-discrimination policies I use estimates by state for 2015 from Andrew Flores, Jody Herman and Christy Mallory.

For more information on how I obtained this data, see the “References” section.

The Flores/Barclay data is contained within the CSV file ssm-support-flores.csv. It contains the following variables:

  • State (chr). Two-letter state abbreviation.
  • Year (int). Year of the estimates.
  • Support_Pct (int). Estimated level of support, as a percentage.
  • CI_Lower (int). Lower end of the confidence interval, as a percentage.
  • CI_Upper (int). Upper end of the confidence interval, as a percentage.

The Lax/Phillips and PRRI data is contained within the CSV files ssm-support-lax.csv and ssm-support-prri.csv respectively. These files contain the same variables as ssm-support-flores.csv, except that there are no confidence intervals. (For the Lax/Phillips data I used the year 1995 as the year for the 1994-1996 estimates.)

The Flores/Herman/Mallory data is contained within the CSV file ti-support-flores.csv. It contains the same variables as the file ssm-support-flores.csv, along with an additional Boolean variable Congruent indicating whether a given state had non-discrimination policies that included transgender individuals.

Finally, I created a test file test-support.csv that contains synthetic test data covering a range of support from zero to 98%. I use this to create a plot legend as discussed below, as well as to check that support percentages are being properly converted to ranges.

To construct the cartograms I use U.S. state population figures from the 2010 census. Using the same figures for all cartograms ensures that the size and arrangement of the circles in each cartogram is the same, so that it’s easier to see the change in attitudes over time.

I check to make sure that I have the files I expect, and stop the analysis if not.

stopifnot(md5sum("ssm-support-lax.csv") == "ed28570d8e557a32aacd68909fc6a8f9")
stopifnot(md5sum("ssm-support-flores.csv") == "0f8c030bd2371a849f9c6778f1408b2e")
stopifnot(md5sum("ssm-support-prri.csv") == "1a97e89f08f23b8e671732e97047aa61")
stopifnot(md5sum("ti-support-flores.csv") == "709a74876478ac3844db2a9758468470")
stopifnot(md5sum("test-support.csv") == "ebc4cf4a7b3d977b63833a87d6896223")
stopifnot(md5sum("DEC_10_SF1_GCTPH1.US01PR.csv") == "fbbcd0ec0e5768099326186489b41ce2")
stopifnot(md5sum("states.csv") == "8e2097ba7fa661b1622238f9cbbca4e0")

Reading in and preparing the data

I begin by reading in the various CSV files:

ssm_support_lax <- read_csv("ssm-support-lax.csv", col_type = "cii")
ssm_support_flores <- read_csv("ssm-support-flores.csv", col_type = "ciiii")
ssm_support_prri <- read_csv("ssm-support-prri.csv", col_type = "cii")
ti_support_flores <- read_csv("ti-support-flores.csv", col_type = "ciiiil")
test_support <- read_csv("test-support.csv", col_type = "cii")
census_2010 <- read_csv("DEC_10_SF1_GCTPH1.US01PR.csv",
                        col_types = "ccccccciiddddd")
states <- read_csv("states.csv", col_types = "cc")

I then extract only the data I need from the Census table, and create a new table pop_2010 with just the population figures. I also save the figure for total U.S. population for use later.

pop_2010 <- census_2010 %>%
  select(`GCT_STUB.display-label_1`, HD01) %>%
  rename(Name = `GCT_STUB.display-label_1`, Population = HD01) %>%
  inner_join(states, by = "Name") %>%
  select(State, Population)
us_pop_2010 <- pop_2010 %>%
  filter(State == "US") %>%
  select(Population) %>%
  as.integer()

Analysis

I want to create cartograms based on both the 2010 population of each state and the support for marriage equality in the years of interest. To begin, I create the following tables that bring together the relevant variables I want to display:

I create the support_1995_lax table as follows:

  1. Start with the ssm_support_lax table.
  2. Filter out the rows for 1995.
  3. Select only the columns with the state and the estimated support for that state.
  4. Join the resulting table with the pop_2010 table using their common field State.
support_1995_lax <- ssm_support_lax %>%
  filter(Year == 1995) %>%
  select(State, Support_Pct) %>%
  inner_join(pop_2010, by = "State")

I create the remaining tables similarly, using the appropriate tables as input and selecting the years of interest.

support_2004_flores <- ssm_support_flores %>%
  filter(Year == 2004) %>%
  select(State, Support_Pct) %>%
  inner_join(pop_2010, by = "State")
support_2010_lax <- ssm_support_lax %>%
  filter(Year == 2010) %>%
  select(State, Support_Pct) %>%
  inner_join(pop_2010, by = "State")
support_2012_flores <- ssm_support_flores %>%
  filter(Year == 2012) %>%
  select(State, Support_Pct) %>%
  inner_join(pop_2010, by = "State")
support_2014_flores <- ssm_support_flores %>%
  filter(Year == 2014) %>%
  select(State, Support_Pct) %>%
  inner_join(pop_2010, by = "State")
support_2014_prri <- ssm_support_prri %>%
  filter(Year == 2014) %>%
  select(State, Support_Pct) %>%
  inner_join(pop_2010, by = "State")
ti_support_2015_flores <- ti_support_flores %>%
  filter(Year == 2015) %>%
  select(State, Support_Pct) %>%
  inner_join(pop_2010, by = "State")
support_2017_prri <- ssm_support_prri %>%
  filter(Year == 2017) %>%
  select(State, Support_Pct) %>%
  inner_join(pop_2010, by = "State")
test_support_2099 <- test_support %>%
  select(State, Support_Pct) %>%
  inner_join(pop_2010, by = "State")

Marriage equality support changes over time

Since I want to plot cartograms for multiple years, I create an R function to perform the necessary steps.

I first define a function assign_range() to convert percentage values into ranges of support. This function will need to take a vector and return a vector, so I use the ifelse function, which is vector-aware, to decide what range a given percentage value falls in.

# @title Convert support percentages into support ranges.
# @param pct Support percentages (vector of integers)

assign_range <- function(pct) {
  # Convert support percentages into support ranges as follows:
  #
  #   1. supermajority (>70%) against (0-29% support)
  #   2. solid majority (>60%) against (30-39% support)
  #   3. majority (>50%) against (40-49% support)
  #   4. majority (>=50%) in favor (50-59% support)
  #   5. solid majority (>=60%) in favor (60-69% support)
  #   6. supermajority (>=70%) in favor (70-100% support)
  ifelse(pct <= 29,
         1, ifelse(pct <= 39,
                   2, ifelse(pct <= 49,
                             3, ifelse(pct <= 59,
                                       4, ifelse(pct <= 69,
                                                 5, 6)))))
}

I then define the function plot_support() to actually produce a cartogram.

# @title Plot one Dorling cartogram for marriage equality support
# @param support_tf Table of support percentages by state
# @param description Description of the cartogram (string)
# @param quiet show Dorling iterations (boolean)

plot_support <- function(support_tf, description, quiet = TRUE) {
  # Rename state variable to iso_3166_2.
  temp_tf <- support_tf %>%
    rename(iso_3166_2 = State)

  # Ranges of support.
  # NOTE: This must match the ranges in the assign_range() function.
  ranges <- ordered(c("0-29%", "30-39%", "40-49%",
                      "50-59%", "60-69%", "70-100%"))

  # Convert each support percentage into the corresponding range.
  temp_tf <- temp_tf %>%
    mutate(Support = ranges[assign_range(Support_Pct)])

  # Set label sizes relative to population, with minimum for small states.
  temp_tf <- temp_tf %>%
    mutate(Label_Size = ifelse(Population > 5000000,
                               Population / 5000000, 1))

  # Get the base map of the lower 48 states.
  usa <- albersusa::usa_composite(proj = "laea") %>%
    subset(!(name %in% c("Alaska", "Hawaii", "District of Columbia")))

  # Add support, population, and label size data to the map data.
  # NOTE: The map already contains population data but its provenance
  # is unclear, so I don't use it.
  usa@data <- usa@data %>%
    left_join(temp_tf, by = "iso_3166_2")

  # Create the cartograms, with the size of circles based on population.
  dor <- dorling_from_sp(usa, value = usa$Population, quiet = quiet)

  # Bind data to the map and convert it all to a data frame.
  dor$discs <- sp::SpatialPolygonsDataFrame(dor$discs,
                                            data=usa@data,
                                            match.ID = FALSE)
  discs_df <- fortify(dor$discs, region = "iso_3166_2") %>%
    left_join(usa@data, by = c("id" = "iso_3166_2")) %>%
    tbl_df()

  # Create a separate data frame with the state labels.
  usa_labs <- as_data_frame(dor$xy) %>%
    set_names(c("lng", "lat")) %>%
    mutate(iso_3166_2 = usa@data$iso_3166_2) %>%
    left_join(usa@data, by = "iso_3166_2")

  # Match palette colors to the ranges of support.
  palette_table <- tibble(Support = ranges,
                          Support_Color = c("red", "orange",
                                            "yellow", "green",
                                            "blue", "purple"))

  # Use a palette with only colors matching the ranges in the data.
  palette <- temp_tf %>%
    inner_join(palette_table, by = "Support") %>%
    arrange(Support) %>%
    select(Support_Color) %>%
    unique() %>%
    pull(Support_Color)

  # Set label colors to contrast with colors representing support ranges.
  #           red      orange   yellow   green    blue     purple
  colors <- c("black", "black", "black", "black", "white", "white")
  label_colors <- colors[usa@data$Support]

  # Add an x-axis label to replace the original "long" (for longitude) text.
  x_axis_text <- description

  # Create the actual cartogram plot.
  ggplot() +
    geom_polygon(
      data = discs_df, aes(long, lat, group=group, fill=Support),
      size=0.125, color="white"
    ) +
    geom_text(
      data = usa_labs,
      aes(lng, lat, label = iso_3166_2, size = Label_Size),
      color = label_colors,
      show.legend = FALSE
    ) +
    scale_fill_manual(values = palette) +
    scale_size_area(name = "Population", labels = scales::comma) +
    coord_fixed() +
    theme(panel.background = element_blank(),
          axis.ticks = element_blank(),
          axis.text = element_blank(),
          ) +
    labs(x = x_axis_text, y = NULL)
}

I now plot the cartograms in order by year, in order to better see changes over time.

I first plot the cartogram for 1994-1996 using the Lax/Phillips data.

plot_support(support_1995_lax,
             "Support for Marriage Equality by State in 1994-1996 (Lax/Phillips)")

I next plot the cartogram for 2004 using the Flores/Barclay data.

plot_support(support_2004_flores,
             "Support for Marriage Equality by State in 2004 (Flores/Barclay)")

I next plot the cartogram for 2010 using the Lax/Phillips data.

plot_support(support_2010_lax,
             "Support for Marriage Equality by State in 2010 (Lax/Phillips)")

I next plot the cartograms for 2012 and 2014 using the Flores/Barclay data.

plot_support(support_2012_flores,
             "Support for Marriage Equality by State in 2012 (Flores/Barclay)")

plot_support(support_2014_flores,
             "Support for Marriage Equality by State in 2014 (Flores/Barclay)")

Finally, I plot the cartograms for 2014 and 2017 using the PRRI data. If the PRRI data is consistent with the Flores/Barclay data then this 2014 cartogram should be similar to the previous 2014 cartogram.

plot_support(support_2014_prri,
             "Support for Marriage Equality by State in 2014 (PRRI)")

plot_support(support_2017_prri,
             "Support for Marriage Equality by State in 2017 (PRRI)")

I also am interested in the number of states in each range of support along with the percentage of the U.S. population represented by each state. I define a function to create a table for this.

# @title Create a table showing ranges of marriage equality support
# @param support_tf Table of support percentages and populations by state

create_support_table <- function(support_tf) {
  # Ranges of support.
  # NOTE: This must match the ranges in the assign_range() function.
  ranges <- ordered(c("0-29%", "30-39%", "40-49%",
                      "50-59%", "60-69%", "70-100%"))

  # Convert each support percentage into the corresponding range.
  temp_tf <- support_tf %>%
    mutate(Support = ranges[assign_range(Support_Pct)])

  # Return number of states and their percentage of the total US
  # population in each range.
  temp_tf %>%
    filter(!(State %in% c("US", "DC", "PR"))) %>%
    group_by(Support) %>%
    summarize(Num_States = n(),
              Population_Pct = round(100 * (sum(Population) / us_pop_2010), 0))
}

I then create a table for each of the datasets in the cartograms above.

Ranges of Support for Marriage Equality in 1994-1996 (Lax/Phillips)
Support Num_States Population_Pct
0-29% 43 77
30-39% 7 23
Ranges of Support for Marriage Equality in 2004 (Flores/Barclay)
Support Num_States Population_Pct
0-29% 25 41
30-39% 20 37
40-49% 5 21
Ranges of Support for Marriage Equality in 2010 (Lax/Phillips)
Support Num_States Population_Pct
0-29% 5 6
30-39% 15 28
40-49% 13 28
50-59% 15 36
60-69% 2 2
Ranges of Support for Marriage Equality in 2012 (Flores/Barclay)
Support Num_States Population_Pct
30-39% 15 29
40-49% 23 39
50-59% 12 31
Ranges of Support for Marriage Equality in 2014 (Flores/Barclay)
Support Num_States Population_Pct
30-39% 5 6
40-49% 9 12
50-59% 16 38
60-69% 13 21
70-100% 7 22
Ranges of Support for Marriage Equality in 2014 (PRRI)
Support Num_States Population_Pct
30-39% 6 8
40-49% 12 24
50-59% 18 36
60-69% 11 29
70-100% 3 3
Ranges of Support for Marriage Equality in 2017 (PRRI)
Support Num_States Population_Pct
40-49% 6 10
50-59% 18 26
60-69% 17 55
70-100% 9 9

I also calculate the ten states with the highest percentage of support for marriage equality in 2017, along with the ten states with the lowest percentages of support.

states_by_support <- support_2017_prri %>%
  arrange(desc(Support_Pct))
top10 <- head(states_by_support, 10)
bottom10 <- tail(states_by_support, 10)

I then display these tables.

Top 10 States for Support of Marriage Equality in 2017 (PRRI)
State Support_Pct Population
MA 80 6547629
VT 80 625741
RI 78 1052567
CT 73 3574097
NH 73 1316470
WA 73 6724540
CO 71 5029196
ME 71 1328361
NV 70 2700551
NY 69 19378102
Bottom 10 States for Support of Marriage Equality in 2017 (PRRI)
State Support_Pct Population
AR 52 2915918
GA 52 9687653
SD 52 814180
KY 51 4339367
NC 49 9535483
LA 48 4533372
WV 48 1852994
TN 46 6346105
MS 42 2967297
AL 41 4779736

The top ten states account for 16% of the total U.S. population. The bottom ten states account for 15% of the total U.S. population.

Inclusion of transgender individuals in non-discrimination policies

I plot a cartogram for support for inclusion of transgender individuals in non-discrimination policies, using the Flores/Herman/Mallory data.

plot_support(ti_support_2015_flores,
             "Support for Inclusion of Transgender Individuals in Non-discrimination Policies by State")

As with marriage equality, I also am interested in the number of states in each range of support along with the percentage of the U.S. population that they represent. I display a table showing this.

Ranges of Support for Transgender Inclusion in 2015
Support Num_States Population_Pct
60-69% 5 4
70-100% 45 95

I also calculate the ten states with the highest percentage of support for inclusion of transgender individuals in non-discrimination policies, along with the ten states with the lowest percentages of support.

states_by_support <- ti_support_2015_flores %>%
  arrange(desc(Support_Pct)) %>%
  select(State, Support_Pct, Population)
top10 <- head(states_by_support, 10)
bottom10 <- tail(states_by_support, 10)

I then display these tables.

Top 10 States for Support of Transgender Inclusion in 2015
State Support_Pct Population
HI 90 1360301
VT 88 625741
DE 87 897934
MD 87 5773552
MA 87 6547629
NY 87 19378102
RI 87 1052567
CA 86 37253956
CT 85 3574097
NJ 85 8791894
Bottom 10 States for Support of Transgender Inclusion in 2015
State Support_Pct Population
ND 71 672591
SD 71 814180
UT 71 2763885
AR 70 2915918
KY 70 4339367
AL 69 4779736
NE 69 1826341
KS 68 2853118
WY 67 563626
OK 66 3751351

The top ten states account for 28% of the total U.S. population. The bottom ten states account for 8% of the total U.S. population.

Finally, I look at states where support for inclusion of transgender individuals in non-discrimination policies is at least 81%, the support threshold hypothesized by Flores, Herman, and Mallory as necessary for the enactment of such policies.

over80 <- ti_support_2015_flores %>%
  filter(!(State %in% c("US", "DC", "PR"))) %>%
  filter(Support_Pct > 80)
n_over80 <- over80 %>%
  summarize(n()) %>%
  as.integer()

There are 19 states with support of 81% or higher, representing 43% of the total U.S. population.

Creating a complete legend

The legends for the above plots do not show the full range of values for support. In order to create a complete legend I plot synthetic data that contains a full range of support percentages.

plot_support(test_support_2099, "Test Plot of Support Data")

Comparing Flores/Barclay and PRRI data

As shown above in the cartograms for 2014, there are some differences in the estimates for support of marriage equality between Flores and Barclay and the PRRI American Values Atlas. To get a better idea of how close the estimates are, I plot the estimates against each other and compute a correlation coefficient between them.

I first create a table flores_vs_prri showing only the support percentages by state from each data source.

flores_vs_prri <- support_2014_flores %>%
  rename(Support_Pct_Flores = Support_Pct) %>%
  select(-Population) %>%
  inner_join(support_2014_prri, by = "State") %>%
  rename(Support_Pct_PRRI = Support_Pct) %>%
  select(-Population)

I then plot the estimates against each other.

flores_vs_prri %>%
  ggplot() +
  geom_text(aes(x = Support_Pct_Flores, y = Support_Pct_PRRI, label = State)) +
  geom_smooth(aes(x = Support_Pct_Flores, y = Support_Pct_PRRI), method = "lm") +
  labs(x = "2014 Support for Marriage Equality (Flores)", y = "2014 Support (PRRI)")

The correlation between the two sets of estimates is 0.9, showing reasonably close agreement.

Appendix

Caveats

The cartograms cover only the lower 48 states. The omission of Alaska, Hawaii, and the District of Columbia is due to a restriction on the part of the spdorling package. The omission of Puerto Rico is due to lack of both map data and support data.

The levels of support for each state are estimated based on collating various polls and surveys. For small states the confidence levels are rather large, up to 20 percentage points. Plotting ranges of support helps convey this fact, but for states that are at or close to the 50% break point for support the resulting plot does not necessarily show how a hypothetical referendum in that state would go.

As noted above, the estimates from Flores and Barclay and from PRRI are not totally consistent. This impacts any comparison between the plot of the Flores/Barclay estimates for 2014 and the PRRI estimates for 2017. The estimates from Lax and Phillips are also not necessarily consistent with estimates from the other two sources.

References

I transcribed estimates of marriage equality support for 1994-1996 and 2010 from the table “Support for Same-Sex Marriage, State by State” accompanying the New York Times article “Over Time, a Gay Marriage Groundswell” by Andrew Gelman, Jeffrey Lax, and Justin Phillips (August 22, 2010, p. WK-3). (The article also has an accompanying interactive map of support by state for various year. The cartogram above for 2010 corresponds to the interactive map for 2010 assuming 45% support nationwide.)

(For more on the research behind this article, see “Gay Rights in the States: Public Opinion and Policy Responsiveness” and “How Should We Estimate Public Opinion in The States?”, both by Lax and Phillips.)

I transcribed estimates of marriage equality support for 2004 and 2012 from Figure 2 on page 6 of “Public Support for Marriage for Same-sex Couples by State”, by Andrew R. Flores and Scott Barclay (April 2013). I transcribed similar estimates for 2014 from Figure 1 on page 3 of “Trends in Public Support for Marriage for Same-Sex Couples by State”, also by Flores and Barclay (April 2015).

I transcribed estimates of marriage equality support from the PRRI survey showing people favoring same-sex marriage in 2014 and the same survey in 2017.

I transcribed estimates of support for inclusion of transgender individuals in non-discrimination policies from “Transgender inclusion in state non-discrimination policies: The democratic deficit and political powerlessness” by Andrew R. Flores, Jody L. Herman and Christy Mallory.

(For a similar discussion of “democratic deficits” with respect to LGBT rights in general, as well as other public policy issues, see “The Democratic Deficit in the States” by Lax and Phillips.)

For those interested, the Wikipedia article “Public opinion of same-sex marriage in the United States” summarizes opinion polls in the U.S. on marriage equality, including national polls as far back as 1988 (in which year only about 1 in 10 Americans favored marriage equality, while two-thirds were opposed). The Gallup organization in particular has done national polls on LGBT issues, including marriage equality, for many years.

Population figures by state for 2010 are from Table GCT-PH1, “Population, Housing Units, Area, and Density: 2010 - United States – States; and Puerto Rico, 2010 Census Summary File 1”, downloaded in CSV format from the US Census Factfinder site, using the link “Compare States for Population, Housing, Area, and Density”.

Environment

I used the following R environment in doing the analysis above:

sessionInfo()
## R version 3.5.1 (2018-07-02)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 18.04.1 LTS
## 
## Matrix products: default
## BLAS: /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.7.1
## LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.7.1
## 
## locale:
##  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
##  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
##  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
## 
## attached base packages:
## [1] tools     stats     graphics  grDevices utils     datasets  methods  
## [8] base     
## 
## other attached packages:
##  [1] bindrcpp_0.2.2  knitr_1.20      spdorling_0.1.0 albersusa_0.3.1
##  [5] forcats_0.3.0   stringr_1.3.1   dplyr_0.7.6     purrr_0.2.5    
##  [9] readr_1.1.1     tidyr_0.8.1     tibble_1.4.2    ggplot2_3.0.0  
## [13] tidyverse_1.2.1
## 
## loaded via a namespace (and not attached):
##  [1] Rcpp_0.12.18      lubridate_1.7.4   lattice_0.20-35  
##  [4] deldir_0.1-15     gtools_3.8.1      class_7.3-14     
##  [7] assertthat_0.2.0  rprojroot_1.3-2   digest_0.6.16    
## [10] R6_2.2.2          cellranger_1.1.0  plyr_1.8.4       
## [13] backports_1.1.2   coda_0.19-1       evaluate_0.11    
## [16] e1071_1.7-0       highr_0.7         httr_1.3.1       
## [19] pillar_1.3.0      rlang_0.2.2       lazyeval_0.2.1   
## [22] spdep_0.7-8       readxl_1.1.0      gdata_2.18.0     
## [25] rstudioapi_0.7    gmodels_2.18.1    Matrix_1.2-14    
## [28] rmarkdown_1.10    labeling_0.3      splines_3.5.1    
## [31] rgdal_1.3-4       foreign_0.8-70    munsell_0.5.0    
## [34] broom_0.5.0       compiler_3.5.1    modelr_0.1.2     
## [37] pkgconfig_2.0.2   rgeos_0.3-28      htmltools_0.3.6  
## [40] tidyselect_0.2.4  expm_0.999-2      crayon_1.3.4     
## [43] withr_2.1.2       sf_0.6-3          MASS_7.3-51      
## [46] grid_3.5.1        nlme_3.1-137      spData_0.2.9.3   
## [49] jsonlite_1.5      gtable_0.2.0      DBI_1.0.0        
## [52] magrittr_1.5      units_0.6-0       scales_1.0.0     
## [55] cli_1.0.0         stringi_1.2.4     LearnBayes_2.15.1
## [58] sp_1.3-1          xml2_1.2.0        boot_1.3-20      
## [61] glue_1.3.0        hms_0.4.2         yaml_2.2.0       
## [64] colorspace_1.3-2  maptools_0.9-3    classInt_0.2-3   
## [67] rvest_0.3.2       bindr_0.1.1       haven_1.1.2

Source code

You can find the source code for this analysis and others at my Seven Answers public Gitlab repository. This document and its source code are available for unrestricted use, distribution and modification under the terms of the Creative Commons CC0 1.0 Universal (CC0 1.0) Public Domain Dedication. Stated more simply, you’re free to do whatever you’d like with it.