Math Camp field notebook

Question, code, evidence, judgment

Policy question

Write one descriptive or associational question. Name the population, outcome, comparison, and time period.

Data and definitions

  • Source: World Bank World Development Indicators
  • Retrieval or snapshot date:
  • Unit of observation: country-year
  • Indicators and units:
  • Known limitations:
library(tidyverse)

wdi <- read_csv(
  "../data/derived/math-camp-wdi-2000-2022.csv",
  show_col_types = FALSE
)

First inspection

Before using an agent, predict what each check should reveal.

glimpse(wdi)
Rows: 4,991
Columns: 15
$ iso3c                       <chr> "ABW", "ABW", "ABW", "ABW", "ABW", "ABW", …
$ country                     <chr> "Aruba", "Aruba", "Aruba", "Aruba", "Aruba…
$ region                      <chr> "Latin America & Caribbean", "Latin Americ…
$ income_level_current        <chr> "High income", "High income", "High income…
$ lending_type_current        <chr> "Not classified", "Not classified", "Not c…
$ year                        <dbl> 2000, 2001, 2002, 2003, 2004, 2005, 2006, …
$ adolescent_fertility        <dbl> 43.729, 40.463, 38.185, 37.807, 38.761, 40…
$ carbon_intensity            <dbl> 0.07890653, 0.07658411, 0.08445188, 0.0962…
$ electricity_access          <dbl> 91.7, 100.0, 100.0, 100.0, 100.0, 100.0, 1…
$ female_secondary_enrollment <dbl> 91.73772, 97.35983, 98.05524, 101.51862, 9…
$ gdp_per_capita_growth       <dbl> 6.51922377, 3.21240569, -1.62809915, -0.03…
$ gdp_per_capita_ppp          <dbl> 37618.993, 38827.467, 38195.318, 38182.393…
$ internet_use                <dbl> 15.442822948, 17.100000000, 18.800000000, …
$ renewable_electricity       <dbl> 0.000000, 0.000000, 0.000000, 0.000000, 0.…
$ under5_mortality            <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
count(wdi, year)
# A tibble: 23 × 2
    year     n
   <dbl> <int>
 1  2000   217
 2  2001   217
 3  2002   217
 4  2003   217
 5  2004   217
 6  2005   217
 7  2006   217
 8  2007   217
 9  2008   217
10  2009   217
# ℹ 13 more rows
summarise(wdi, economies = n_distinct(iso3c))
# A tibble: 1 × 1
  economies
      <int>
1       217

Analysis sample

Explain every filter and transformation in plain language.

# Replace this example with the variables for your selected policy track.
analysis_data <- wdi |>
  select(iso3c, country, year, income_level_current,
         gdp_per_capita_ppp, under5_mortality) |>
  filter(
    year >= 2000,
    !is.na(gdp_per_capita_ppp),
    gdp_per_capita_ppp > 0,
    !is.na(under5_mortality)
  ) |>
  mutate(log_income = log(gdp_per_capita_ppp))

stopifnot(
  !anyDuplicated(analysis_data[c("iso3c", "year")])
)

Comparison

ggplot(analysis_data, aes(log_income, under5_mortality)) +
  geom_point(alpha = 0.4, na.rm = TRUE) +
  labs(
    x = "Log GDP per capita, PPP",
    y = "Under-five deaths per 1,000 live births"
  ) +
  theme_minimal()

Scatterplot of log GDP per capita and under-five mortality for complete country-year observations.

Replace this caption with the population, variables, years, and units.

Write the strongest descriptive or associational statement supported by the output.

Simple model and interpretation

Translate the coefficient on log_income into percentage changes that a reader can recognize.

fit <- lm(
  under5_mortality ~ log_income + income_level_current,
  data = analysis_data
)

beta <- unname(coef(fit)[["log_income"]])
tibble(
  comparison = c("10% higher GDP per capita", "double GDP per capita"),
  estimated_change_in_deaths_per_1000 = c(
    beta * log(1.10),
    beta * log(2)
  )
)
# A tibble: 2 × 2
  comparison                estimated_change_in_deaths_per_1000
  <chr>                                                   <dbl>
1 10% higher GDP per capita                               -1.47
2 double GDP per capita                                  -10.7 

Write both interpretations as pooled associations among observations in the same included current income-level category. Causal interpretation requires a separate research design.

Residual check

diagnostics <- analysis_data |>
  mutate(
    fitted = predict(fit),
    residual = resid(fit)
  ) |>
  arrange(desc(abs(residual)))

diagnostics |>
  select(country, year, under5_mortality, fitted, residual) |>
  slice_head(n = 8)
# A tibble: 8 × 5
  country                   year under5_mortality fitted residual
  <chr>                    <dbl>            <dbl>  <dbl>    <dbl>
1 Central African Republic  2009             489.  112.      378.
2 Central African Republic  2022             425.  115.      310.
3 Somalia, Fed. Rep.        2011             363.  116.      247.
4 Central African Republic  2019             255.  115.      140.
5 Equatorial Guinea         2001             150.   18.7     131.
6 Angola                    2000             185    54.8     130.
7 Equatorial Guinea         2000             154.   25.3     129.
8 Equatorial Guinea         2002             146.   16.9     129.

Choose one row. Record what you checked before proposing a substantive story for why its observed value differs from the fitted value.

Limitation

Name at least one limitation related to measurement, missingness, comparison, or causal interpretation.

AI-use note

I used [Codex / Claude Code / other] to [explain, generate, debug, review, or update]. I provided it with [public project context]. I verified its contribution by [tests, source comparison, clean render, or manual review]. I revised or rejected [important example]. I remain responsible for the analysis and interpretation.

Verification record

Agent claim or change Check performed Result
Confirmed / contradicted / unresolved

Clean-session receipt

Restart R, choose Session → Restart R, then render this notebook without running chunks manually. Record:

  • render date and time;
  • R version from R.version.string;
  • number of model observations from nobs(fit);
  • whether the HTML opened without an error;
  • any warning you investigated and resolved or documented.

Handoff checklist