library(ipumsr)
library(tidyverse)
library(writexl)DREAM Act Fact Sheet 2025 Update (using CPS data)
DREAM Act Fact Sheet 2025 Update - CPS Data
Methods
I used 2019-2024 Current Population Survey Annual Social and Economic Supplements (CPS ASEC) data from IPUMS CPS. I filtered the data for Texas (fips=48) before downloading the extract.
I used the following variables:
I limited the sample to immigrants—defined as individuals who are either naturalized citizens or non-citizens—aged 25 and older who worked full-time, year-round in the previous year. Following the Census Bureau’s definition, full-time, year-round workers are those who worked 50 to 52 weeks and typically worked 35 or more hours per week. Additionally, I excluded all observations with negative or missing income values (INCWAGE) to prevent skewing the results.
To calculate the median income by educational attainment, I used the matrixStats package, specifically the weightedMedian function, to account for sample weights. The dataset was first split by educational attainment category (educ_c) and year using the split function. For each subgroup, I computed the weighted median of individual income (incwage), applying the appropriate person-level weight (asecwt) to ensure the estimates accurately reflected the population. The resulting median income values were compiled into a consolidated dataset containing the educational category, year, and corresponding weighted median income.
Data Prep
# Load CPS data extract (years 2019-2024)
ddi <- read_ipums_ddi("cps_00027.xml")
data <- read_ipums_micro(ddi, data_file = "cps_00027.dat", verbose = FALSE)
data <- rename_with(data, tolower)
print(data)# A tibble: 58,960 × 17
year serial month cpsid asecflag asecwth statefip pernum cpsidp cpsidv
<dbl> <dbl> <int+l> <dbl> <int+lb> <dbl> <int+lb> <dbl> <dbl> <dbl>
1 2019 64127 3 [Mar… 2.02e13 1 [ASEC] 3485. 48 [Tex… 1 2.02e13 2.02e14
2 2019 64127 3 [Mar… 2.02e13 1 [ASEC] 3485. 48 [Tex… 2 2.02e13 2.02e14
3 2019 64128 3 [Mar… 2.02e13 1 [ASEC] 3415. 48 [Tex… 1 2.02e13 2.02e14
4 2019 64128 3 [Mar… 2.02e13 1 [ASEC] 3415. 48 [Tex… 2 2.02e13 2.02e14
5 2019 64130 3 [Mar… 2.02e13 1 [ASEC] 1524. 48 [Tex… 1 2.02e13 2.02e14
6 2019 64130 3 [Mar… 2.02e13 1 [ASEC] 1524. 48 [Tex… 2 2.02e13 2.02e14
7 2019 64132 3 [Mar… 2.02e13 1 [ASEC] 3264. 48 [Tex… 1 2.02e13 2.02e14
8 2019 64132 3 [Mar… 2.02e13 1 [ASEC] 3264. 48 [Tex… 2 2.02e13 2.02e14
9 2019 64133 3 [Mar… 2.02e13 1 [ASEC] 3597. 48 [Tex… 1 2.02e13 2.02e14
10 2019 64134 3 [Mar… 2.02e13 1 [ASEC] 1707. 48 [Tex… 1 2.02e13 2.02e14
# ℹ 58,950 more rows
# ℹ 7 more variables: asecwt <dbl>, age <int+lbl>, citizen <int+lbl>,
# uhrswork1 <int+lbl>, educ <int+lbl>, wkswork1 <dbl>, incwage <dbl+lbl>
EDUC Educational attainment recode
073 High school diploma or equivalent
081 Some college but no degree
091 Associate's degree, occupational/vocational program
092 Associate's degree, academic program
111 Bachelor's degree
123 Master's degree
124 Professional school degree
125 Doctorate degree
CITIZEN Citizenship status
1 Born in U.S
2 Born in U.S. outlying
3 Born abroad of American parents
4 Naturalized citizen
5 Not a citizen
data <- data %>%
mutate(
educ_c = case_when(
educ == 073 ~ "1. High school diploma or equivalent",
educ == 081 ~ "2. Some college",
educ %in% c (091, 092) ~ "3. Associate's degree",
educ %in% c (111, 123, 124, 125) ~ "4. Bachelor's degree or higher",
TRUE ~ NA_character_),
incwage = as.numeric(incwage)
) %>%
filter(
!is.na(incwage) & incwage > 0,
citizen %in% c (4, 5), # filter for immigrants
age >=25,
uhrswork1 >= 35, # worked full-time (Census defines FT as 35+ hours)
wkswork1 >= 50, # worked year-round (Census defines YR as 50-52 weeks)
)
print(data)# A tibble: 4,986 × 18
year serial month cpsid asecflag asecwth statefip pernum cpsidp cpsidv
<dbl> <dbl> <int+l> <dbl> <int+lb> <dbl> <int+lb> <dbl> <dbl> <dbl>
1 2019 64143 3 [Mar… 2.02e13 1 [ASEC] 1825. 48 [Tex… 2 2.02e13 2.02e14
2 2019 64179 3 [Mar… 0 1 [ASEC] 1559. 48 [Tex… 2 0 0
3 2019 64229 3 [Mar… 2.02e13 1 [ASEC] 1816. 48 [Tex… 2 2.02e13 2.02e14
4 2019 64240 3 [Mar… 0 1 [ASEC] 1715. 48 [Tex… 1 0 0
5 2019 64241 3 [Mar… 0 1 [ASEC] 1908. 48 [Tex… 2 0 0
6 2019 64249 3 [Mar… 2.02e13 1 [ASEC] 1705. 48 [Tex… 1 2.02e13 2.02e14
7 2019 64281 3 [Mar… 0 1 [ASEC] 1748. 48 [Tex… 1 0 0
8 2019 64281 3 [Mar… 0 1 [ASEC] 1748. 48 [Tex… 2 0 0
9 2019 64283 3 [Mar… 0 1 [ASEC] 2012. 48 [Tex… 1 0 0
10 2019 64297 3 [Mar… 0 1 [ASEC] 1532. 48 [Tex… 2 0 0
# ℹ 4,976 more rows
# ℹ 8 more variables: asecwt <dbl>, age <int+lbl>, citizen <int+lbl>,
# uhrswork1 <int+lbl>, educ <int+lbl>, wkswork1 <dbl>, incwage <dbl>,
# educ_c <chr>
Option 1: Average Income (what Kimberly used)
library(survey)Loading required package: grid
Loading required package: Matrix
Attaching package: 'Matrix'
The following objects are masked from 'package:tidyr':
expand, pack, unpack
Loading required package: survival
Attaching package: 'survey'
The following object is masked from 'package:graphics':
dotchart
design <- svydesign(
ids = ~1,
weights = ~asecwt,
data = data
)
# calculate weighted mean by educational attainment
average_income <- svyby(~incwage, ~educ_c + year, design, svymean, na.rm = TRUE)
print(average_income) educ_c
1. High school diploma or equivalent.2019 1. High school diploma or equivalent
2. Some college.2019 2. Some college
3. Associate's degree.2019 3. Associate's degree
4. Bachelor's degree or higher.2019 4. Bachelor's degree or higher
1. High school diploma or equivalent.2020 1. High school diploma or equivalent
2. Some college.2020 2. Some college
3. Associate's degree.2020 3. Associate's degree
4. Bachelor's degree or higher.2020 4. Bachelor's degree or higher
1. High school diploma or equivalent.2021 1. High school diploma or equivalent
2. Some college.2021 2. Some college
3. Associate's degree.2021 3. Associate's degree
4. Bachelor's degree or higher.2021 4. Bachelor's degree or higher
1. High school diploma or equivalent.2022 1. High school diploma or equivalent
2. Some college.2022 2. Some college
3. Associate's degree.2022 3. Associate's degree
4. Bachelor's degree or higher.2022 4. Bachelor's degree or higher
1. High school diploma or equivalent.2023 1. High school diploma or equivalent
2. Some college.2023 2. Some college
3. Associate's degree.2023 3. Associate's degree
4. Bachelor's degree or higher.2023 4. Bachelor's degree or higher
1. High school diploma or equivalent.2024 1. High school diploma or equivalent
2. Some college.2024 2. Some college
3. Associate's degree.2024 3. Associate's degree
4. Bachelor's degree or higher.2024 4. Bachelor's degree or higher
year incwage se
1. High school diploma or equivalent.2019 2019 48702.02 7055.821
2. Some college.2019 2019 47078.02 3042.362
3. Associate's degree.2019 2019 47125.58 4186.374
4. Bachelor's degree or higher.2019 2019 84144.22 4467.888
1. High school diploma or equivalent.2020 2020 40473.66 1817.282
2. Some college.2020 2020 44199.27 3777.086
3. Associate's degree.2020 2020 47881.28 4221.161
4. Bachelor's degree or higher.2020 2020 107676.82 7815.497
1. High school diploma or equivalent.2021 2021 48579.10 6878.944
2. Some college.2021 2021 54015.71 5835.273
3. Associate's degree.2021 2021 80873.70 33806.863
4. Bachelor's degree or higher.2021 2021 88311.58 3654.968
1. High school diploma or equivalent.2022 2022 49219.46 5469.583
2. Some college.2022 2022 49233.56 3579.261
3. Associate's degree.2022 2022 52473.91 4284.003
4. Bachelor's degree or higher.2022 2022 102231.51 5410.848
1. High school diploma or equivalent.2023 2023 51133.27 4921.609
2. Some college.2023 2023 52012.16 3594.296
3. Associate's degree.2023 2023 50117.43 3401.418
4. Bachelor's degree or higher.2023 2023 109231.32 4921.163
1. High school diploma or equivalent.2024 2024 42118.89 1631.949
2. Some college.2024 2024 50019.62 2993.086
3. Associate's degree.2024 2024 61037.69 4721.616
4. Bachelor's degree or higher.2024 2024 107218.25 6222.215
View(average_income)Option 2: Median Income (my recommendation)
library(matrixStats)Warning: package 'matrixStats' was built under R version 4.2.3
Attaching package: 'matrixStats'
The following object is masked from 'package:dplyr':
count
# calculate weighted median by educational attainment
median_income_data <- do.call(rbind, lapply(split(data, list(data$educ_c, data$year)), function(subset_data) {
if (nrow(subset_data) > 0) {
median_value <- weightedMedian(subset_data$incwage, subset_data$asecwt, na.rm = TRUE)
data.frame(educd_c = unique(subset_data$educ_c), year = unique(subset_data$year), median_income = median_value)
}
}))
print(median_income_data) educd_c
1. High school diploma or equivalent.2019 1. High school diploma or equivalent
2. Some college.2019 2. Some college
3. Associate's degree.2019 3. Associate's degree
4. Bachelor's degree or higher.2019 4. Bachelor's degree or higher
1. High school diploma or equivalent.2020 1. High school diploma or equivalent
2. Some college.2020 2. Some college
3. Associate's degree.2020 3. Associate's degree
4. Bachelor's degree or higher.2020 4. Bachelor's degree or higher
1. High school diploma or equivalent.2021 1. High school diploma or equivalent
2. Some college.2021 2. Some college
3. Associate's degree.2021 3. Associate's degree
4. Bachelor's degree or higher.2021 4. Bachelor's degree or higher
1. High school diploma or equivalent.2022 1. High school diploma or equivalent
2. Some college.2022 2. Some college
3. Associate's degree.2022 3. Associate's degree
4. Bachelor's degree or higher.2022 4. Bachelor's degree or higher
1. High school diploma or equivalent.2023 1. High school diploma or equivalent
2. Some college.2023 2. Some college
3. Associate's degree.2023 3. Associate's degree
4. Bachelor's degree or higher.2023 4. Bachelor's degree or higher
1. High school diploma or equivalent.2024 1. High school diploma or equivalent
2. Some college.2024 2. Some college
3. Associate's degree.2024 3. Associate's degree
4. Bachelor's degree or higher.2024 4. Bachelor's degree or higher
year median_income
1. High school diploma or equivalent.2019 2019 35000.00
2. Some college.2019 2019 40801.14
3. Associate's degree.2019 2019 37678.72
4. Bachelor's degree or higher.2019 2019 69469.91
1. High school diploma or equivalent.2020 2020 35000.00
2. Some college.2020 2020 32000.00
3. Associate's degree.2020 2020 38733.13
4. Bachelor's degree or higher.2020 2020 80000.00
1. High school diploma or equivalent.2021 2021 31151.41
2. Some college.2021 2021 47244.62
3. Associate's degree.2021 2021 40000.00
4. Bachelor's degree or higher.2021 2021 72378.48
1. High school diploma or equivalent.2022 2022 36321.70
2. Some college.2022 2022 45263.24
3. Associate's degree.2022 2022 45000.00
4. Bachelor's degree or higher.2022 2022 80000.00
1. High school diploma or equivalent.2023 2023 35752.84
2. Some college.2023 2023 44954.20
3. Associate's degree.2023 2023 49546.51
4. Bachelor's degree or higher.2023 2023 90000.00
1. High school diploma or equivalent.2024 2024 36000.00
2. Some college.2024 2024 47595.00
3. Associate's degree.2024 2024 52314.91
4. Bachelor's degree or higher.2024 2024 80190.80
View(median_income_data)# Save to excel
write_xlsx(list(Sheet1 = median_income_data, Sheet2 = average_income), "immigrant_inc_CPS_FT.xlsx")