eda with ipums data

The code below shows some basic exploratory data analysis (EDA) with the IPUMS dataset. The goal is to get a sense of the distribution of rent burden by degree field, and to see if there are any patterns by sex or race.

load librariqes and data

# how much data we got?
library(haven)
library(tidyverse)
ipums_2024 <- read_rds(
    'https://euclid.nmu.edu/~joshthom/dat309/data/IPUMS/ipums_2024.rds'
)

size, shape, and classes present in the data

# count the number of rows in the dataset
ipums_2024 |> count()
# A tibble: 1 × 1
        n
    <int>
1 3422888
# count the number of columns in the dataset
ipums_2024 |> ncol()
[1] 20
# get the datatypes of each column in the dataset
glimpse(ipums_2024)
Rows: 3,422,888
Columns: 20
$ year      <int> 2024, 2024, 2024, 2024, 2024, 2024, 2024, 2024, 2024, 2024, …
$ sample    <int+lbl> 202401, 202401, 202401, 202401, 202401, 202401, 202401, …
$ serial    <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 1…
$ cbserial  <dbl> 2.02401e+12, 2.02401e+12, 2.02401e+12, 2.02401e+12, 2.02401e…
$ hhwt      <dbl> 41, 52, 31, 4, 19, 64, 56, 40, 74, 40, 63, 55, 22, 3, 17, 52…
$ cluster   <dbl> 2.024e+12, 2.024e+12, 2.024e+12, 2.024e+12, 2.024e+12, 2.024…
$ strata    <dbl> 250001, 260001, 140101, 280201, 80001, 200001, 170001, 14040…
$ rentgrs   <int+lbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ pernum    <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …
$ perwt     <dbl> 41, 52, 31, 4, 19, 64, 56, 40, 74, 40, 63, 55, 22, 3, 17, 52…
$ sex       <fct> Male, Male, Female, Female, Male, Male, Male, Male, Female, …
$ age       <int+lbl> 59, 43, 75, 22, 51, 20, 66, 28, 18, 64, 21, 19, 55, 35, …
$ race      <fct> "Black/African American", "White", "Black/African American",…
$ raced     <int+lbl> 234, 177, 234, 600, 177, 177, 201, 234, 234, 177, 201, 1…
$ degfield  <fct> "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A…
$ degfieldd <int+lbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ uhrswork  <int+lbl> 30, 0, 0, 0, 0, 0, 0, 72, 20, 0, 0, 0, 0, 0, 40, 35, 15,…
$ inctot    <dbl+lbl> 18500,     0, 27100,  1000,     0,     0, 16400, 30000, …
$ tranwork  <fct> "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A…
$ trantime  <dbl+lbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0,…
# alternative one-liner to get a basic summary of the dataset
# uncomment below to install skim
# pak::pkg_install("skimr")
library(skimr)
skim(ipums_2024)
Data summary
Name ipums_2024
Number of rows 3422888
Number of columns 20
_______________________
Column type frequency:
factor 4
numeric 16
________________________
Group variables None

Variable type: factor

skim_variable n_missing complete_rate ordered n_unique top_counts
sex 0 1 FALSE 2 Fem: 1743242, Mal: 1679646, Mis: 0
race 0 1 FALSE 9 Whi: 2286695, Two: 361498, Bla: 292257, Oth: 194306
degfield 0 1 FALSE 38 N/A: 2459111, Bus: 186514, Edu: 113999, Med: 78613
tranwork 0 1 FALSE 13 N/A: 1845121, Aut: 1234645, Wor: 217824, Wal: 43305

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
year 0 1 2.024000e+03 0.00 2.02400e+03 2.024000e+03 2.024000e+03 2.024000e+03 2.024000e+03 ▁▁▇▁▁
sample 0 1 2.024010e+05 0.00 2.02401e+05 2.024010e+05 2.024010e+05 2.024010e+05 2.024010e+05 ▁▁▇▁▁
serial 0 1 7.645721e+05 445088.53 1.00000e+00 3.748090e+05 7.616925e+05 1.155867e+06 1.531614e+06 ▇▇▇▇▇
cbserial 0 1 2.024001e+12 2146567.19 2.02400e+12 2.024000e+12 2.024001e+12 2.024001e+12 2.024010e+12 ▇▁▁▁▁
hhwt 0 1 9.768000e+01 89.49 1.00000e+00 4.700000e+01 7.100000e+01 1.150000e+02 2.300000e+03 ▇▁▁▁▁
cluster 0 1 2.024008e+12 4450885.26 2.02400e+12 2.024004e+12 2.024008e+12 2.024012e+12 2.024015e+12 ▇▇▇▇▇
strata 0 1 4.887943e+05 847235.38 1.00010e+04 1.000010e+05 2.306480e+05 4.798120e+05 8.100351e+06 ▇▁▁▁▁
rentgrs 0 1 3.843500e+02 893.42 0.00000e+00 0.000000e+00 0.000000e+00 0.000000e+00 1.323300e+04 ▇▁▁▁▁
pernum 0 1 2.050000e+00 1.33 1.00000e+00 1.000000e+00 2.000000e+00 3.000000e+00 2.000000e+01 ▇▁▁▁▁
perwt 0 1 9.936000e+01 91.78 1.00000e+00 4.700000e+01 7.200000e+01 1.170000e+02 2.300000e+03 ▇▁▁▁▁
age 0 1 4.339000e+01 24.03 0.00000e+00 2.300000e+01 4.400000e+01 6.400000e+01 9.600000e+01 ▆▇▇▇▂
raced 0 1 2.965600e+02 247.66 1.01000e+02 1.380000e+02 1.770000e+02 2.340000e+02 9.900000e+02 ▇▁▁▁▁
degfieldd 0 1 1.222150e+03 2155.60 0.00000e+00 0.000000e+00 0.000000e+00 2.300000e+03 6.403000e+03 ▇▁▁▁▂
uhrswork 0 1 1.936000e+01 20.98 0.00000e+00 0.000000e+00 8.000000e+00 4.000000e+01 9.900000e+01 ▇▂▅▁▁
inctot 0 1 1.536766e+06 3542444.43 -1.15000e+04 1.380000e+04 4.400000e+04 1.095000e+05 9.999999e+06 ▇▁▁▁▂
trantime 0 1 1.081000e+01 19.83 0.00000e+00 0.000000e+00 0.000000e+00 1.500000e+01 1.950000e+02 ▇▁▁▁▁
sk <- skim(ipums_2024)

select columns and filter anomalies

Filtering anomalies is a choice. It will depend on your research question and the type of analysis you want to do. For example, if you are interested in rent burden, you may want to filter out those with no rent or no income. If you are interested in commute time, you may want to filter out those with no commute time or those who work from home. The code below is an example of how to filter the data for those with a degree field, full-time workers, and not overworked.

cn <- ipums_2024 |> colnames()
cols2drop <- c(2,3,4,5,6,7,10,14,16)

# drop the columns we don't need
ipums_2024 <- ipums_2024 |> select(-cn[cols2drop])

# filter the dataset to only include rows with complete data
ipm <- ipums_2024 |> filter(
    degfield != "N/A", # only include those with a degree field
    uhrswork >= 35, # full-time workers
    uhrswork <= 60, # not overworked
)

See what data is n/a or coded strangely

ipm <- ipm |> mutate(
    insign = case_when(
        inctot == 9999999 ~ "N/A",
        inctot < 0 ~ "Negative",
        TRUE ~ "Valid"
    ),
    .after = 1
)

# see how many rows are in each category
ipm |> count(insign)
# A tibble: 2 × 2
  insign        n
  <chr>     <int>
1 Negative    159
2 Valid    557840

rent burden

Next, we can create a new variable:

NoteDefinition

rent burden: the ratio of annual rent to annual income

We also define a categorical variable for rent burden using case_when(). The syntax is as follows:

case_when(
    condition1 ~ value1, # this gets evaluated first
    condition2 ~ value2, # this gets evaluated second
    TRUE ~ default_value # catch-all case
)

We also filter out any rows with missing values for rent or income.

ipm <- ipm |> 
    filter(rentgrs != 0, insign == "Valid") |>
    mutate(
        rent_burden = (rentgrs * 12) / inctot,
        rel_rent_burden = case_when(
            rent_burden < 0.3 ~ "Low",
            rent_burden >= 0.3 & rent_burden < 0.5 ~ "Moderate",
            rent_burden >= 0.5 ~ "High"),
        scale_rent_burden = rent_burden - 0.3
        )

Coarse distribution of rent burden by degree field

group_by(ipm, degfield) |> 
    summarise(
        mean_rent_burden = mean(rent_burden, na.rm = TRUE),
        median_rent_burden = median(rent_burden, na.rm = TRUE),
        sd_rent_burden = sd(rent_burden, na.rm = TRUE),
        count = n()
    ) |>
    arrange(desc(mean_rent_burden)) |>
    print(n = 100)
# A tibble: 37 × 5
   degfield             mean_rent_burden median_rent_burden sd_rent_burden count
   <fct>                           <dbl>              <dbl>          <dbl> <int>
 1 History                         3.40               0.338        135.     2192
 2 Law                             3.22               0.354         37.0     213
 3 Physical Fitness, P…            2.06               0.379         62.0    1901
 4 Psychology                      1.82               0.368         71.9    6668
 5 Biology and Life Sc…            1.54               0.362         75.3    7145
 6 Social Sciences                 1.11               0.342         48.1    9731
 7 Business                        1.07               0.339         59.2   21470
 8 Fine Arts                       0.974              0.397         20.5    6626
 9 Medical and Health …            0.933              0.330         19.9    8191
10 Communications                  0.734              0.36          11.5    6138
11 Agriculture                     0.733              0.324          5.63   1089
12 Computer and Inform…            0.722              0.282         13.2    6255
13 Linguistics and For…            0.700              0.357          3.79   1246
14 Interdisciplinary a…            0.639              0.362          2.55   1349
15 Military Technologi…            0.634              0.396          0.860    14
16 Cosmetology Service…            0.633              0.458          0.702   129
17 Family and Consumer…            0.616              0.387          1.66    892
18 Education Administr…            0.604              0.355          2.79   6979
19 Communication Techn…            0.586              0.379          1.27    353
20 Criminal Justice an…            0.583              0.337          2.81   2389
21 Electrical and Mech…            0.570              0.374          0.808    30
22 Environment and Nat…            0.569              0.384          1.01   1213
23 Theology and Religi…            0.559              0.367          0.995   650
24 Area, Ethnic, and C…            0.555              0.363          0.809   544
25 Architecture                    0.553              0.366          0.768  1037
26 Mathematics and Sta…            0.552              0.305          1.43   1714
27 English Language, L…            0.536              0.353          1.04   3592
28 Liberal Arts and Hu…            0.520              0.354          0.779  1254
29 Transportation Scie…            0.518              0.317          0.856   295
30 Philosophy and Reli…            0.514              0.354          0.662   895
31 Engineering                     0.501              0.284          1.55  11607
32 Public Affairs, Pol…            0.496              0.340          0.862  1670
33 Physical Sciences               0.490              0.326          1.31   3522
34 Construction Servic…            0.445              0.306          0.652   228
35 Engineering Technol…            0.407              0.269          0.608   826
36 Nuclear, Industrial…            0.405              0.348          0.260    38
37 Library Science                 0.398              0.318          0.299    24

functions

Here we briefly introduce functions. They are useful for speeding up analysis and simplifying code. We will use them to calculate the distribution of commute time by variable, and return a summary table with mean, median, and count

The main syntax is:

my_function <- function(arg1, arg2) {
    # do something with arg1 and arg2
    return(result)

Notice the {arg1} syntax. This is called “curly-curly” and it allows us to pass a variable name to the function, rather than a value. This is useful for dplyr functions like group_by() and summarise(), which expect variable names rather than values.

distribution_by_var <- function(data, var1, var2) {
    data |> group_by({{var1}}) |> 
        summarise(
            mn = mean({{var2}}, na.rm = TRUE),
            mdn = median({{var2}}, na.rm = TRUE),
            count = n()
        ) |>
        arrange(desc(mn))
}

For example, these two calls to the function will return the same result:

# the function call 
distribution_by_var(ipm, degfield, inctot) |> head()
# A tibble: 6 × 4
  degfield                               mn   mdn count
  <fct>                               <dbl> <dbl> <int>
1 Computer and Information Sciences 116718. 93000  6255
2 Engineering                       114186. 92000 11607
3 Mathematics and Statistics        108918. 80000  1714
4 Engineering Technologies          101235. 84000   826
5 Social Sciences                    98920. 75000  9731
6 Construction Services              97445. 80040   228

compared to

# the full syntax 
ipm |> group_by(degfield) |> 
    summarise(
        mean_income = mean(inctot, na.rm = TRUE),
        median_income = median(inctot, na.rm = TRUE),
        count = n()
    ) |>
    arrange(desc(mean_income)) |> 
    head()
# A tibble: 6 × 4
  degfield                          mean_income median_income count
  <fct>                                   <dbl>         <dbl> <int>
1 Computer and Information Sciences     116718.         93000  6255
2 Engineering                           114186.         92000 11607
3 Mathematics and Statistics            108918.         80000  1714
4 Engineering Technologies              101235.         84000   826
5 Social Sciences                        98920.         75000  9731
6 Construction Services                  97445.         80040   228

But also, you can use the function to get the distribution of commute time by degree field.

histograms

Since rent_burden is a continuous variable, we can visualize its distribution using histograms. We can also facet the histogram by degfield to see how the distribution varies across degree fields.

ipm |> filter(rent_burden < 1) |>
    ggplot(aes(x = rent_burden, fill = degfield)) +
    geom_histogram(bins = 30, position = 'dodge') +
    labs(
        title = "Distribution of Rent Burden by Degree Field",
        x = "Rent Burden (Annual Rent / Annual Income)",
        y = "Count"
    ) +
    theme_minimal() +
    theme(legend.position = "none") 
Figure 1
ipm |> filter(rent_burden < 1) |>
    ggplot(aes(x = rent_burden, fill = degfield)) +
    geom_histogram(bins = 30) +
    labs(
        title = "Distribution of Rent Burden by Degree Field",
        x = "Rent Burden (Annual Rent / Annual Income)",
        y = "Count"
    ) +
    facet_wrap(~degfield) +
    theme_minimal() +
    theme(legend.position = "none") 
Figure 2

The problem with the above histogram is that it is hard to see the distribution of rent burden for each degree field because the scales are different.

count

Remember, there are multiple ways to count. Suppose we wish to count all the people with a specific degfield and rent burden category.

ipm |> count(degfield, rel_rent_burden) |>
    arrange(desc(n)) |>
    print(n = 100)
# A tibble: 111 × 3
    degfield                                               rel_rent_burden     n
    <fct>                                                  <chr>           <int>
  1 Business                                               Low              8945
  2 Business                                               Moderate         6539
  3 Engineering                                            Low              6236
  4 Business                                               High             5986
  5 Social Sciences                                        Low              4014
  6 Medical and Health Sciences and Services               Low              3513
  7 Computer and Information Sciences                      Low              3398
  8 Engineering                                            Moderate         2986
  9 Social Sciences                                        Moderate         2986
 10 Social Sciences                                        High             2731
 11 Biology and Life Sciences                              Low              2687
 12 Education Administration and Teaching                  Low              2643
 13 Medical and Health Sciences and Services               Moderate         2555
 14 Engineering                                            High             2385
 15 Psychology                                             Low              2362
 16 Fine Arts                                              High             2359
 17 Education Administration and Teaching                  Moderate         2350
 18 Communications                                         Low              2278
 19 Biology and Life Sciences                              Moderate         2233
 20 Biology and Life Sciences                              High             2225
 21 Psychology                                             Moderate         2186
 22 Fine Arts                                              Moderate         2182
 23 Medical and Health Sciences and Services               High             2123
 24 Psychology                                             High             2120
 25 Fine Arts                                              Low              2085
 26 Communications                                         Moderate         2054
 27 Education Administration and Teaching                  High             1986
 28 Communications                                         High             1806
 29 Computer and Information Sciences                      Moderate         1580
 30 Physical Sciences                                      Low              1555
 31 English Language, Literature, and Composition          Low              1390
 32 Computer and Information Sciences                      High             1277
 33 English Language, Literature, and Composition          Moderate         1162
 34 Physical Sciences                                      Moderate         1064
 35 English Language, Literature, and Composition          High             1040
 36 Criminal Justice and Fire Protection                   Low               974
 37 History                                                Low               930
 38 Physical Sciences                                      High              903
 39 Mathematics and Statistics                             Low               843
 40 Criminal Justice and Fire Protection                   Moderate          795
 41 Physical Fitness, Parks, Recreation, and Leisure       Moderate          689
 42 History                                                Moderate          681
 43 Public Affairs, Policy, and Social Work                Low               663
 44 Physical Fitness, Parks, Recreation, and Leisure       Low               626
 45 Criminal Justice and Fire Protection                   High              620
 46 Physical Fitness, Parks, Recreation, and Leisure       High              586
 47 History                                                High              581
 48 Public Affairs, Policy, and Social Work                Moderate          556
 49 Liberal Arts and Humanities                            Low               501
 50 Agriculture                                            Low               488
 51 Engineering Technologies                               Low               486
 52 Interdisciplinary and Multi-Disciplinary Studies (Gen… Low               482
 53 Linguistics and Foreign Languages                      Low               477
 54 Interdisciplinary and Multi-Disciplinary Studies (Gen… Moderate          469
 55 Public Affairs, Policy, and Social Work                High              451
 56 Mathematics and Statistics                             Moderate          450
 57 Mathematics and Statistics                             High              421
 58 Environment and Natural Resources                      Low               420
 59 Linguistics and Foreign Languages                      Moderate          416
 60 Environment and Natural Resources                      Moderate          409
 61 Interdisciplinary and Multi-Disciplinary Studies (Gen… High              398
 62 Liberal Arts and Humanities                            Moderate          389
 63 Environment and Natural Resources                      High              384
 64 Liberal Arts and Humanities                            High              364
 65 Architecture                                           Low               361
 66 Philosophy and Religious Studies                       Low               360
 67 Architecture                                           Moderate          354
 68 Linguistics and Foreign Languages                      High              353
 69 Architecture                                           High              322
 70 Family and Consumer Sciences                           Moderate          319
 71 Agriculture                                            Moderate          304
 72 Agriculture                                            High              297
 73 Family and Consumer Sciences                           High              294
 74 Family and Consumer Sciences                           Low               279
 75 Philosophy and Religious Studies                       Moderate          273
 76 Philosophy and Religious Studies                       High              262
 77 Theology and Religious Vocations                       Low               251
 78 Theology and Religious Vocations                       High              217
 79 Area, Ethnic, and Civilization Studies                 Low               208
 80 Engineering Technologies                               Moderate          203
 81 Theology and Religious Vocations                       Moderate          182
 82 Area, Ethnic, and Civilization Studies                 Moderate          180
 83 Area, Ethnic, and Civilization Studies                 High              156
 84 Engineering Technologies                               High              137
 85 Transportation Sciences and Technologies               Low               137
 86 Communication Technologies                             Moderate          131
 87 Communication Technologies                             Low               113
 88 Construction Services                                  Low               111
 89 Communication Technologies                             High              109
 90 Transportation Sciences and Technologies               Moderate           95
 91 Law                                                    Low                86
 92 Construction Services                                  Moderate           73
 93 Law                                                    Moderate           67
 94 Transportation Sciences and Technologies               High               63
 95 Law                                                    High               60
 96 Cosmetology Services and Culinary Arts                 High               59
 97 Construction Services                                  High               44
 98 Cosmetology Services and Culinary Arts                 Moderate           37
 99 Cosmetology Services and Culinary Arts                 Low                33
100 Nuclear, Industrial Radiology, and Biological Technol… Low                17
# ℹ 11 more rows

is the same as this

ipm |> group_by(degfield, rel_rent_burden) |>
    summarise(count = n()) |>
    arrange(desc(count)) |>
    print(n = 100)
# A tibble: 111 × 3
# Groups:   degfield [37]
    degfield                                               rel_rent_burden count
    <fct>                                                  <chr>           <int>
  1 Business                                               Low              8945
  2 Business                                               Moderate         6539
  3 Engineering                                            Low              6236
  4 Business                                               High             5986
  5 Social Sciences                                        Low              4014
  6 Medical and Health Sciences and Services               Low              3513
  7 Computer and Information Sciences                      Low              3398
  8 Engineering                                            Moderate         2986
  9 Social Sciences                                        Moderate         2986
 10 Social Sciences                                        High             2731
 11 Biology and Life Sciences                              Low              2687
 12 Education Administration and Teaching                  Low              2643
 13 Medical and Health Sciences and Services               Moderate         2555
 14 Engineering                                            High             2385
 15 Psychology                                             Low              2362
 16 Fine Arts                                              High             2359
 17 Education Administration and Teaching                  Moderate         2350
 18 Communications                                         Low              2278
 19 Biology and Life Sciences                              Moderate         2233
 20 Biology and Life Sciences                              High             2225
 21 Psychology                                             Moderate         2186
 22 Fine Arts                                              Moderate         2182
 23 Medical and Health Sciences and Services               High             2123
 24 Psychology                                             High             2120
 25 Fine Arts                                              Low              2085
 26 Communications                                         Moderate         2054
 27 Education Administration and Teaching                  High             1986
 28 Communications                                         High             1806
 29 Computer and Information Sciences                      Moderate         1580
 30 Physical Sciences                                      Low              1555
 31 English Language, Literature, and Composition          Low              1390
 32 Computer and Information Sciences                      High             1277
 33 English Language, Literature, and Composition          Moderate         1162
 34 Physical Sciences                                      Moderate         1064
 35 English Language, Literature, and Composition          High             1040
 36 Criminal Justice and Fire Protection                   Low               974
 37 History                                                Low               930
 38 Physical Sciences                                      High              903
 39 Mathematics and Statistics                             Low               843
 40 Criminal Justice and Fire Protection                   Moderate          795
 41 Physical Fitness, Parks, Recreation, and Leisure       Moderate          689
 42 History                                                Moderate          681
 43 Public Affairs, Policy, and Social Work                Low               663
 44 Physical Fitness, Parks, Recreation, and Leisure       Low               626
 45 Criminal Justice and Fire Protection                   High              620
 46 Physical Fitness, Parks, Recreation, and Leisure       High              586
 47 History                                                High              581
 48 Public Affairs, Policy, and Social Work                Moderate          556
 49 Liberal Arts and Humanities                            Low               501
 50 Agriculture                                            Low               488
 51 Engineering Technologies                               Low               486
 52 Interdisciplinary and Multi-Disciplinary Studies (Gen… Low               482
 53 Linguistics and Foreign Languages                      Low               477
 54 Interdisciplinary and Multi-Disciplinary Studies (Gen… Moderate          469
 55 Public Affairs, Policy, and Social Work                High              451
 56 Mathematics and Statistics                             Moderate          450
 57 Mathematics and Statistics                             High              421
 58 Environment and Natural Resources                      Low               420
 59 Linguistics and Foreign Languages                      Moderate          416
 60 Environment and Natural Resources                      Moderate          409
 61 Interdisciplinary and Multi-Disciplinary Studies (Gen… High              398
 62 Liberal Arts and Humanities                            Moderate          389
 63 Environment and Natural Resources                      High              384
 64 Liberal Arts and Humanities                            High              364
 65 Architecture                                           Low               361
 66 Philosophy and Religious Studies                       Low               360
 67 Architecture                                           Moderate          354
 68 Linguistics and Foreign Languages                      High              353
 69 Architecture                                           High              322
 70 Family and Consumer Sciences                           Moderate          319
 71 Agriculture                                            Moderate          304
 72 Agriculture                                            High              297
 73 Family and Consumer Sciences                           High              294
 74 Family and Consumer Sciences                           Low               279
 75 Philosophy and Religious Studies                       Moderate          273
 76 Philosophy and Religious Studies                       High              262
 77 Theology and Religious Vocations                       Low               251
 78 Theology and Religious Vocations                       High              217
 79 Area, Ethnic, and Civilization Studies                 Low               208
 80 Engineering Technologies                               Moderate          203
 81 Theology and Religious Vocations                       Moderate          182
 82 Area, Ethnic, and Civilization Studies                 Moderate          180
 83 Area, Ethnic, and Civilization Studies                 High              156
 84 Engineering Technologies                               High              137
 85 Transportation Sciences and Technologies               Low               137
 86 Communication Technologies                             Moderate          131
 87 Communication Technologies                             Low               113
 88 Construction Services                                  Low               111
 89 Communication Technologies                             High              109
 90 Transportation Sciences and Technologies               Moderate           95
 91 Law                                                    Low                86
 92 Construction Services                                  Moderate           73
 93 Law                                                    Moderate           67
 94 Transportation Sciences and Technologies               High               63
 95 Law                                                    High               60
 96 Cosmetology Services and Culinary Arts                 High               59
 97 Construction Services                                  High               44
 98 Cosmetology Services and Culinary Arts                 Moderate           37
 99 Cosmetology Services and Culinary Arts                 Low                33
100 Nuclear, Industrial Radiology, and Biological Technol… Low                17
# ℹ 11 more rows

proportions

What proportion of each degfield is in each rent burden category?

rent_cat <- ipm |> group_by(degfield, rel_rent_burden) |>
    summarise(count = n()) |>
    mutate(prop = count / sum(count)) |>
    arrange(desc(prop))

rent_cat |> filter(rel_rent_burden == 'High') |> arrange(desc(prop)) |>
    print(n = 100)
# A tibble: 37 × 4
# Groups:   degfield [37]
   degfield                                          rel_rent_burden count  prop
   <fct>                                             <chr>           <int> <dbl>
 1 Cosmetology Services and Culinary Arts            High               59 0.457
 2 Military Technologies                             High                6 0.429
 3 Fine Arts                                         High             2359 0.356
 4 Theology and Religious Vocations                  High              217 0.334
 5 Family and Consumer Sciences                      High              294 0.330
 6 Psychology                                        High             2120 0.318
 7 Environment and Natural Resources                 High              384 0.317
 8 Biology and Life Sciences                         High             2225 0.311
 9 Architecture                                      High              322 0.311
10 Communication Technologies                        High              109 0.309
11 Physical Fitness, Parks, Recreation, and Leisure  High              586 0.308
12 Interdisciplinary and Multi-Disciplinary Studies… High              398 0.295
13 Communications                                    High             1806 0.294
14 Philosophy and Religious Studies                  High              262 0.293
15 Liberal Arts and Humanities                       High              364 0.290
16 English Language, Literature, and Composition     High             1040 0.290
17 Area, Ethnic, and Civilization Studies            High              156 0.287
18 Education Administration and Teaching             High             1986 0.285
19 Linguistics and Foreign Languages                 High              353 0.283
20 Law                                               High               60 0.282
21 Social Sciences                                   High             2731 0.281
22 Business                                          High             5986 0.279
23 Agriculture                                       High              297 0.273
24 Public Affairs, Policy, and Social Work           High              451 0.270
25 Electrical and Mechanic Repairs and Technologies  High                8 0.267
26 History                                           High              581 0.265
27 Criminal Justice and Fire Protection              High              620 0.260
28 Medical and Health Sciences and Services          High             2123 0.259
29 Physical Sciences                                 High              903 0.256
30 Mathematics and Statistics                        High              421 0.246
31 Transportation Sciences and Technologies          High               63 0.214
32 Engineering                                       High             2385 0.205
33 Computer and Information Sciences                 High             1277 0.204
34 Construction Services                             High               44 0.193
35 Nuclear, Industrial Radiology, and Biological Te… High                7 0.184
36 Library Science                                   High                4 0.167
37 Engineering Technologies                          High              137 0.166

scatterplots

The example below shows a scatterplot of rent burden by degfield. It is poor. Why?

ipm |> filter(rent_burden < 10) |>
    ggplot(aes(x = rent_burden, y = reorder(degfield,scale_rent_burden))) +
    geom_vline(xintercept = 0.3, linetype = "dashed", color = "red") +
    geom_point() +
    scale_fill_manual(values = c("Low" = "green", "Moderate" = "yellow", "High" = "red")) +
    labs(
        title = "Divergent Bar Graph of Rent Burden",
        x = "Rent Burden (Annual Rent / Annual Income) - 0.3",
        y = "Count",
        fill = "Rent Burden Category"
    ) +
    theme_minimal()
Figure 3

Get a sense of the distribution of rent burden. That is, how many people are in each category of rent burden, and

ipm |> relocate(rent_burden) |> 
    arrange(desc(rent_burden)) |> 
    head(100) |> 
    print(n=100)
# A tibble: 100 × 15
    rent_burden  year insign rentgrs  pernum sex   age   race  degfield uhrswork
          <dbl> <int> <chr>  <int+lb>  <dbl> <fct> <int> <fct> <fct>    <int+lb>
  1      8550    2024 Valid  2850          1 Male  51    White Business 50      
  2      6360    2024 Valid  2120          1 Male  30    White Biology… 40      
  3      6312    2024 Valid  2104          1 Male  59    White History  40      
  4      5700    2024 Valid  1900          2 Fema… 45    Blac… Psychol… 40      
  5      4740    2024 Valid  1580          2 Fema… 28    White Social … 40      
  6      2702.   2024 Valid  2252          1 Fema… 26    White Physica… 45      
  7      1620    2024 Valid  2700          2 Male  35    Blac… Fine Ar… 40      
  8      1440    2024 Valid  1200          1 Fema… 28    Two … Medical… 40      
  9      1327.   2024 Valid  2212          1 Male  40    White Business 40      
 10      1027.   2024 Valid  3423          1 Male  33    White Medical… 40      
 11      1020    2024 Valid  1700          1 Male  33    Blac… Compute… 60      
 12      1002    2024 Valid  1670          1 Fema… 42    Othe… Psychol… 36      
 13       892.   2024 Valid  2972          1 Fema… 32    White Communi… 40      
 14       879    2024 Valid  2930          1 Male  25    White Psychol… 40      
 15       540    2024 Valid  1800          1 Fema… 31    White Law      35      
 16       468    2024 Valid  1950          1 Fema… 29    White Business 40      
 17       396.   2024 Valid  3297          1 Fema… 43    White Psychol… 40      
 18       352    2024 Valid  1760          1 Fema… 36    Othe… Fine Ar… 60      
 19       323    2024 Valid  3230          3 Fema… 25    Two … Medical… 40      
 20       230.   2024 Valid  2870          1 Male  36    White Social … 40      
 21       183.   2024 Valid  3817          2 Fema… 39    White Educati… 40      
 22       181.   2024 Valid  1505          1 Male  39    White Agricul… 60      
 23       157.   2024 Valid  5248          3 Male  30    White Compute… 40      
 24       130.   2024 Valid  2810          1 Fema… 27    White Biology… 36      
 25       126.   2024 Valid  2621          2 Fema… 38    White Linguis… 40      
 26       117.   2024 Valid  1270          2 Fema… 27    Two … Psychol… 55      
 27       116.   2024 Valid  2898          3 Fema… 22    Two … Crimina… 40      
 28       114.   2024 Valid   858          1 Male  48    White Business 60      
 29       107.   2024 Valid  1247          1 Male  36    Two … Compute… 40      
 30        95.6  2024 Valid  5100          5 Fema… 43    White Social … 40      
 31        92    2024 Valid  1150          1 Fema… 30    White Fine Ar… 40      
 32        90.7  2024 Valid  3780          5 Fema… 23    Othe… Compute… 45      
 33        85.3  2024 Valid  3555          1 Fema… 27    White Interdi… 40      
 34        85.3  2024 Valid  1777          2 Fema… 45    Othe… Fine Ar… 50      
 35        82.9  2024 Valid  1382          2 Male  37    Othe… Enginee… 40      
 36        78.4  2024 Valid  5878          1 Fema… 24    White Educati… 40      
 37        73.7  2024 Valid  4605          1 Fema… 37    Othe… Business 40      
 38        68.4  2024 Valid  3648          3 Fema… 23    Othe… Biology… 40      
 39        67.0  2024 Valid  5580          4 Male  22    Chin… Physica… 40      
 40        66.8  2024 Valid  2060          1 Fema… 48    Othe… Social … 40      
 41        64.9  2024 Valid  1483          1 Fema… 49    White Business 60      
 42        63.4  2024 Valid  1057          2 Male  49    White Communi… 40      
 43        59.5  2024 Valid  2480          1 Fema… 26    White Social … 40      
 44        58.6  2024 Valid  4880          1 Fema… 22    Two … Medical… 36      
 45        58.5  2024 Valid  3410          2 Fema… 28    Two … Business 40      
 46        58.4  2024 Valid  2094          2 Fema… 28    White Biology… 40      
 47        57.8  2024 Valid  2890          2 Fema… 25    White Medical… 40      
 48        55.7  2024 Valid  2553          3 Male  51    White Communi… 36      
 49        55.4  2024 Valid  2908          1 Fema… 33    White Educati… 40      
 50        54.6  2024 Valid  2730          3 Fema… 24    White Fine Ar… 40      
 51        54.4  2024 Valid  1360          2 Fema… 33    Othe… Social … 40      
 52        53.9  2024 Valid  5618          2 Fema… 43    Othe… Educati… 40      
 53        53.1  2024 Valid  2744          1 Male  22    White Business 40      
 54        52.8  2024 Valid  2858          2 Fema… 36    White Medical… 36      
 55        52.6  2024 Valid  1315          2 Fema… 26    White Medical… 40      
 56        52.5  2024 Valid  1750          1 Male  23    Two … Business 40      
 57        51.8  2024 Valid  2160          1 Male  37    Two … Business 50      
 58        51.8  2024 Valid  1725          2 Male  21    Othe… Enginee… 40      
 59        48.1  2024 Valid  4408          2 Fema… 35    White Medical… 45      
 60        47.3  2024 Valid  1300          1 Fema… 30    Amer… Biology… 40      
 61        46.6  2024 Valid  2950          2 Fema… 28    Othe… Compute… 40      
 62        46.6  2024 Valid  3220          2 Male  51    Othe… Medical… 40      
 63        45.6  2024 Valid  2280          3 Fema… 23    Othe… Communi… 55      
 64        45.3  2024 Valid  1360          1 Fema… 45    White Crimina… 40      
 65        44.4  2024 Valid  2000          1 Fema… 47    White Medical… 41      
 66        43.6  2024 Valid  2180          2 Male  29    Othe… Enginee… 45      
 67        41.9  2024 Valid  3490          4 Male  22    Chin… Enginee… 40      
 68        41.1  2024 Valid  2636          1 Fema… 31    White Business 40      
 69        39.4  2024 Valid  9200          1 Male  62    White Business 50      
 70        39.3  2024 Valid  1770          1 Fema… 51    White Communi… 41      
 71        38.8  2024 Valid  1940          2 Fema… 23    Othe… Compute… 55      
 72        38.6  2024 Valid   933          1 Fema… 23    Two … Medical… 37      
 73        38.5  2024 Valid   770          1 Male  58    Blac… Enginee… 40      
 74        38.4  2024 Valid  3200          2 Fema… 30    Othe… Family … 40      
 75        38.4  2024 Valid  1600          1 Fema… 23    White Educati… 40      
 76        38.2  2024 Valid  7000          1 Male  23    Chin… Social … 35      
 77        38    2024 Valid  1900          2 Fema… 22    Othe… Crimina… 55      
 78        37.8  2024 Valid  4100          2 Male  36    White Business 40      
 79        37.0  2024 Valid  1543          2 Male  27    Blac… Physica… 45      
 80        36.9  2024 Valid  3686          5 Fema… 40    Othe… English… 40      
 81        36.9  2024 Valid  1290          2 Fema… 46    Two … Business 60      
 82        36.8  2024 Valid  1930          3 Male  27    Two … Business 37      
 83        36.5  2024 Valid  3040          2 Male  39    Blac… Business 50      
 84        36.3  2024 Valid  7087          2 Male  42    Two … Fine Ar… 40      
 85        36.3  2024 Valid  4239          2 Fema… 54    Amer… Compute… 40      
 86        36.3  2024 Valid  1513          1 Fema… 59    White Fine Ar… 40      
 87        35.7  2024 Valid  1220          2 Fema… 41    White Business 40      
 88        35.3  2024 Valid  2940          3 Male  24    Two … Psychol… 40      
 89        35.0  2024 Valid  1457          5 Male  22    White Compute… 40      
 90        34.9  2024 Valid  4950          3 Fema… 44    Othe… Business 45      
 91        34.9  2024 Valid   843          1 Fema… 25    White Agricul… 35      
 92        34.8  2024 Valid  1450          1 Fema… 22    White Enginee… 40      
 93        34.8  2024 Valid  2754          2 Male  24    Othe… Compute… 40      
 94        34.4  2024 Valid  3435          2 Male  22    White Enginee… 35      
 95        34.1  2024 Valid  1565          2 Male  68    Blac… Social … 35      
 96        33.6  2024 Valid  2800          2 Male  31    Othe… History  40      
 97        33.4  2024 Valid  1755          2 Male  29    White Biology… 37      
 98        33.4  2024 Valid  3620          3 Male  22    Othe… Mathema… 50      
 99        32.7  2024 Valid  4090          1 Fema… 29    White Biology… 50      
100        31.8  2024 Valid  2654          1 Fema… 35    Two … Fine Ar… 45      
# ℹ 5 more variables: inctot <dbl+lbl>, tranwork <fct>, trantime <dbl+lbl>,
#   rel_rent_burden <chr>, scale_rent_burden <dbl>

There is too much data for that chart to be useful. Let’s look at the distribution of the people across the rent burden categories. We can do this with a histogram.

ipm |> ggplot(
    aes(x=rent_burden, fill = rel_rent_burden)) + 
    geom_histogram(bins = 30)

or a barchart

ipm |> ggplot(
    aes(x=rel_rent_burden, fill = rel_rent_burden)) + 
    geom_bar()

ipm |> filter(rent_burden < 1) |>
    ggplot(aes(x = rent_burden)) +
    geom_histogram(bins = 30) +
    labs(
        title = "Distribution of Rent Burden",
        x = "Rent Burden (Annual Rent / Annual Income)",
        y = "Count"
    ) +
    theme_minimal()
Figure 4

summarize rent_burden by degfield

rent_sum <- ipm |> group_by(degfield) |>
    summarise(
        mean_rent_burden = mean(rent_burden, na.rm = TRUE),
        median_rent_burden = median(rent_burden, na.rm = TRUE),
        count = n()
    ) |>
    mutate(
        degfield = fct_reorder(degfield, median_rent_burden)
    )  |> 
    arrange(desc(degfield)) 

visualize rent_burden summary by degfield

rent_sum |> ggplot(
    aes(y = reorder(degfield, median_rent_burden), x = median_rent_burden, fill = degfield)) + 
    geom_col()
Figure 5

lollipop graph of rent_burden summary by degfield

rent_sum |> ggplot(
    aes(y = degfield, x = median_rent_burden)) + 
    geom_segment(aes(x = 0, xend = median_rent_burden, y = degfield, yend = degfield), color = "grey") +
    geom_point(aes(color = degfield),size = 4) +
    labs(
        title = "Median Rent Burden by Degree Field",
        x = "Median Rent Burden (Annual Rent / Annual Income)",
        y = "Degree Field"
    ) +
    theme_minimal() +
    theme(legend.position = "none")
Figure 6
rent_race_sum <- ipm |> group_by(degfield,sex) |>
    summarise(
        mean_rent_burden = mean(rent_burden, na.rm = TRUE),
        median_rent_burden = median(rent_burden, na.rm = TRUE),
        count = n()
    ) |>
    mutate(
        degfield = fct_reorder(degfield, median_rent_burden)
    )  |> 
    arrange(desc(degfield)) 

rent_race_sum |> ggplot(
    aes(y = degfield, x = median_rent_burden)) + 
    geom_segment(aes(x = 0, xend = median_rent_burden, y = degfield, yend = degfield), color = "grey") +
    geom_point(aes(color = degfield),size = 4) +
    labs(
        title = "Median Rent Burden by Degree Field",
        x = "Median Rent Burden (Annual Rent / Annual Income)",
        y = "Degree Field"
    ) +
    theme_minimal() +
    theme(legend.position = "none") + 
    facet_wrap(~sex)
Figure 7

divergent bar graph of rent burden by degfield and sex

rent_race_sum |>
    mutate(
        median_rent_burden = 
            ifelse(sex == "Male", 
                   -median_rent_burden, 
                    median_rent_burden)
    ) |>
    ggplot(aes(x = median_rent_burden, y = degfield, fill = sex)) +
    geom_bar(stat = "identity") +
    geom_vline(xintercept = 0.3, linetype = "dashed", color = "red") +
    geom_vline(xintercept = -0.3, linetype = "dashed", color = "red") +
    scale_x_continuous(labels = abs) +
    labs(
        title = "Divergent Bar Graph of Median Rent Burden by Degree Field and Sex",
        x = "Median Rent Burden (Annual Rent / Annual Income)",
        y = "Degree Field",
        fill = "Sex"
    ) +
    theme_minimal()
Figure 8
# year 2006
ipums_2006 <- read_rds('https://euclid.nmu.edu/~joshthom/dat309/data/IPUMS/ipums_2006.rds')

# year 2016
ipums_2016 <- read_rds('https://euclid.nmu.edu/~joshthom/dat309/data/IPUMS/ipums_2016.rds')

# year 2024
ipums_2024 <- read_rds('https://euclid.nmu.edu/~joshthom/dat309/data/IPUMS/ipums_2024.rds')

ipums_all <- left_join(ipums_2006,ipums_2016) ipums_all <- left_join(ipums_all,ipums_2024) write_rds(ipums_all, ‘../data/IPUMS/ipums_full.rds’)