Lab 4: Tables

TipHow to complete the lab

You are encouraged to work together and get started in class. Talk through the problems with the people around you. Then, you will finish the lab on your own time and submit your work individually to Blackboard.

AI use: You may use AI to ask questions or debug, but not to write your code for you. The point is to think it through yourself.

Overview

In this lab you will make three of the displays we built in class, using slightly different data: a polished gt table of Census income data, a table with sparklines of V-Dem democracy scores, and a plot of income estimates with confidence intervals. You will need your Census API key.

# load your libraries and set your Census API key here

Step 1: A gt table (50 pts)

In class we made a table of income quintiles for a selection of states. Now do the same for the counties in a state of your choice. Use get_acs() to download the mean household income of each quintile (B19081_001 through B19081_006) with geography = "county", your state, and year = 2023. Clean the data as we did in class, and use str_replace_all() so that only the county name shows (e.g. “Franklin” rather than “Franklin County, Ohio”).

Then pick 6–10 counties to display. You could take the highest- and lowest-income counties, as we did in class, or counties you know. Make a great (or awesome!) gt table with a title and subtitle that describe your selection, relabeled columns, dollar formatting, a source note, and at least two of the styling steps from class (column widths, font, alignment, borders). Below the table, say in a sentence which counties stand out.

Finally, save your table with gtsave() as an HTML file (e.g. "county_table.html").

Step 2: A sparkline table (30 pts)

In class we made sparklines of electoral democracy (v2x_polyarchy) for the BRICS countries. Now choose a different group of 5–8 countries (for example the G7, or a set of neighbors) and a different V-Dem democracy index, such as liberal democracy (v2x_libdem), participatory democracy (v2x_partipdem) or egalitarian democracy (v2x_egaldem). Use vdem from vdemdata to keep the years 2000–2025 for your countries. Then summarize the max, mean and standard deviation of your index for each country, and make a gt table with a sparkline of its trend using gt_plt_sparkline(). Give the columns clear labels and round the numbers to two decimals. Below the table, describe in a sentence what the sparklines show.

Step 3: Confidence intervals (20 pts)

In class we plotted median income for the counties in Massachusetts with 90% confidence intervals. Now choose a different state and download median household income (B19013_001) by county for 2023. Compute the lower and upper bounds of the 90% confidence interval from the margin of error, and plot the estimates with geom_point() and geom_errorbar(). Give the plot a title, subtitle and caption. Below the plot, say in a sentence what the error bars show that a table of estimates would not.

Bonus (extra credit)

Completing this bonus restores full credit on one quiz where you lost points. If you have not lost points on any quiz, you will get 2 points of extra credit on this lab instead.

We will approximate Fearon and Laitin’s Ethnicity, Insurgency, and Civil War, whose provocative claim is that ethnic diversity per se does not predict civil conflict. Build a country-year data frame with peacesciencer:

library(peacesciencer)

conflict_df <- create_stateyears(system = "gw") |>
  filter(year %in% c(1946:2019)) |>
  add_ucdp_acd(type = "intrastate", only_wars = FALSE) |>
  add_democracy() |>
  add_creg_fractionalization() |>
  add_sim_gdp_pop() |>
  mutate(gdppc = log(mrgdppc), # log GDP per capita
         pop = log(pwtpop))    # log population

Use glm() with family = "binomial" to fit two models of conflict onset (ucdponset). One should include ethnic fractionalization (ethfrac) and one should include democracy (v2x_polyarchy), and both should control for gdppc and pop. Display the two models side by side with modelsummary(), and use modelplot() to make a coefficient plot of one of them. In a sentence, say whether your results support Fearon and Laitin’s claim.


ImportantSubmission Instructions

Head over to Blackboard and go to the Lab 4 assignment. Click “Create Submission” and write a brief statement saying that you have submitted the lab and note whether and in what capacity you used AI on the assignment.

Then upload a compressed (zipped) version of your project folder including the rendered HTML file. To compress your project folder, right-click it and choose Compress (Mac) or Send to → Compressed (zipped) folder (Windows).


Hints

Only look at these if you’re stuck!

Hint 1 — Which packages do I need?

Load the tidyverse (which includes dplyr, stringr and ggplot2), plus:

Step Packages
1 tidycensus, gt
2 vdemdata, gt, gtExtras (for gt_plt_sparkline())
3 tidycensus, janitor (for clean_names())
Bonus peacesciencer, modelsummary (for both modelsummary() and modelplot())

You only need to load each package once, so put all of your library() calls in the setup chunk.

Hint 2 — “A Census API key is required”:

Set your key in the setup chunk before you call get_acs():

library(tidycensus)
census_api_key("YOUR API KEY")

Hint 3 — Picking your counties:

You can stack the counties you want with bind_rows(), as we did with states in class, or pick them by name:

my_counties <- county_quintiles |>
  filter(name %in% c("Franklin", "Cuyahoga", "Hamilton", "Delaware", "Athens", "Holmes"))

Hint 4 — County names that won’t clean up:

A few states don’t call all of their counties “counties.” Louisiana has parishes, Alaska has boroughs, and Virginia has independent cities. If some names still have endings after str_replace_all(), add a second str_replace_all() for the other ending, or just choose a different state.

Hint 5 — V-Dem country codes:

Filter on country_text_id, which uses three-letter codes. The G7, for example, is:

filter(country_text_id %in% c("USA", "GBR", "FRA", "DEU", "ITA", "JPN", "CAN"))

Hint 6 — Too many counties to read in your plot:

If your state has a lot of counties, the plot in Step 3 will be crowded. Plot a subset, for example the 20 highest-income counties with slice_max(estimate, n = 20) or 20 random ones with slice_sample(n = 20), and say so in your subtitle.