Minimum Wages and Employment: A Case Study of the Fast-Food Industry in New Jersey and Pennsylvania Replication
1 Introduction
On April 1, 1992, New Jersey increased its minimum wage from $4.25 to $5.05 per hour, while Pennsylvania maintained the federal minimum wage of $4.25. This policy change created a natural experiment to study the employment effects of minimum wage increases. Card and Krueger collected data from fast-food restaurants in both states before (February 1992) and after (November 1992) the policy change.The paper can be accesed from here.
2 Data and Methodology
2.1 Data Collection
The datasets from this code can found David Card’s UC Berkerly faculty page.
The study uses survey data from fast-food restaurants collected in two waves: - Wave 1: February 1992 (before the minimum wage increase) - Wave 2: November 1992 (after the minimum wage increase)
The sample includes four major fast-food chains: Burger King, KFC, Roy Rogers, and Wendy’s.
2.2 Data Preparation
The data preparation process involves importing the raw survey data and creating a comprehensive labeling system for all variables. The dataset is imported using a dictionary file that defines variable structures, followed by systematic labeling of all categorical variables including restaurant chains (Burger King, KFC, Roy Rogers, Wendys), states (Pennsylvania as control, New Jersey as treatment), employee benefits, survey response status, and various binary indicators for ownership type and regional locations.
cd "D:\njmin"
* Here I use a dictionary file that I prepared based on the codebook description
infile using "D:\njmin\njmin.dct", using("D:\njmin\public.dat") clear
label define CHAIN 1 "Burger King" 2 "KFC" 3 "Roy Rogers" 4 "Wendys"
label values CHAIN CHAIN
label define STATE 0 "Pennsylvania" 1 "New Jersey"
label values STATE STATE
label define MEALS 0 "None" 1 "Free meals" 2 "Reduced price" 3 "Both"
label values MEALS MEALS
label values MEALS2 MEALS
label define STATUS2 0 "Refused" 1 "Completed" 2 "Closed for renovation" 3 "Closed permanently" 4 "Highway construction" 5 "Mall fire"
label values STATUS2 STATUS2
label define YESNO 0 "No" 1 "Yes"
foreach var in CO_OWNED SOUTHJ CENTRALJ NORTHJ PA1 PA2 SHORE BONUS SPECIAL2 {
label values `var' YESNO
}D:\njmin
dictionary {
_column(1) SHEET %3.0f "Store ID number"
_column(5) CHAIN %1.0f "Chain: 1=Burger King, 2=KFC, 3=Roy Rogers
> , 4=Wendys"
_column(7) CO_OWNED %1.0f "Company owned: 1=yes, 0=no"
_column(9) STATE %1.0f "State: 1=New Jersey, 0=Pennsylvania"
_column(11) SOUTHJ %1.0f "Southern NJ: 1=yes, 0=no"
_column(13) CENTRALJ %1.0f "Central NJ: 1=yes, 0=no"
_column(15) NORTHJ %1.0f "Northern NJ: 1=yes, 0=no"
_column(17) PA1 %1.0f "PA northeast suburbs: 1=yes, 0=no"
_column(19) PA2 %1.0f "PA Easton etc: 1=yes, 0=no"
_column(21) SHORE %1.0f "NJ shore: 1=yes, 0=no"
_column(23) NCALLS %2.0f "Number of call-backs (0 if first call)"
_column(26) EMPFT %5.2f "Full-time employees (wave 1)"
_column(32) EMPPT %5.2f "Part-time employees (wave 1)"
_column(38) NMGRS %5.2f "Managers/assistants (wave 1)"
_column(44) WAGE_ST %5.2f "Starting wage ($/hr, wave 1)"
_column(50) INCTIME %5.1f "Months to first raise (wave 1)"
_column(56) FIRSTINC %5.2f "Usual first raise amount ($/hr, wave 1)"
_column(62) BONUS %1.0f "Cash bounty for new workers: 1=yes, 0=no"
_column(64) PCTAFF %5.1f "% employees affected by new minimum"
_column(70) MEALS %1.0f "Free/reduced meal code (wave 1)"
_column(72) OPEN %5.2f "Hour of opening (wave 1)"
_column(78) HRSOPEN %5.2f "Hours open per day (wave 1)"
_column(84) PSODA %5.2f "Price of medium soda w/tax (wave 1)"
_column(90) PFRY %5.2f "Price of small fries w/tax (wave 1)"
_column(96) PENTREE %5.2f "Price of entree w/tax (wave 1)"
_column(102) NREGS %2.0f "Number of cash registers (wave 1)"
_column(105) NREGS11 %2.0f "Registers open at 11am (wave 1)"
_column(108) TYPE2 %1.0f "Interview type: 1=phone, 2=personal"
_column(110) STATUS2 %1.0f "Interview status (see codebook)"
_column(112) DATE2 %6.0f "Interview date (MMDDYY format)"
_column(119) NCALLS2 %2.0f "Number of call-backs (wave 2)"
_column(122) EMPFT2 %5.2f "Full-time employees (wave 2)"
_column(128) EMPPT2 %5.2f "Part-time employees (wave 2)"
_column(134) NMGRS2 %5.2f "Managers/assistants (wave 2)"
_column(140) WAGE_ST2 %5.2f "Starting wage ($/hr, wave 2)"
_column(146) INCTIME2 %5.1f "Months to first raise (wave 2)"
_column(152) FIRSTIN2 %5.2f "Usual first raise amount ($/hr, wave 2)"
_column(158) SPECIAL2 %1.0f "Special program: 1=yes, 0=no"
_column(160) MEALS2 %1.0f "Free/reduced meal code (wave 2)"
_column(162) OPEN2R %5.2f "Hour of opening (wave 2)"
_column(168) HRSOPEN2 %5.2f "Hours open per day (wave 2)"
_column(174) PSODA2 %5.2f "Price of medium soda w/tax (wave 2)"
_column(180) PFRY2 %5.2f "Price of small fries w/tax (wave 2)"
_column(186) PENTREE2 %5.2f "Price of entree w/tax (wave 2)"
_column(192) NREGS2 %2.0f "Number of cash registers (wave 2)"
_column(195) NREGS112 %2.0f "Registers open at 11am (wave 2)"
}
(410 observations read)
2.3 Data Processing
The raw dataset contains interview dates in a compressed numeric format that requires processing to create proper date variables. The conversion process involves extracting date components, handling 2-digit to 4-digit year conversion, and formatting dates for STATA’s internal date system.
tostring DATE2, gen(DATE2_str) format(%06.0f)
gen str2 mm = substr(DATE2_str, 1, 2)
gen str2 dd = substr(DATE2_str, 3, 2)
gen str2 yy = substr(DATE2_str, 5, 2)
gen str4 yyyy = cond(real(yy) < 30, "20" + yy, "19" + yy)
gen str10 DATE2_fmt = mm + "/" + dd + "/" + yyyy
gen date2 = date(DATE2_fmt, "MDY")
format date2 %td
label variable date2 "Second interview date"
drop DATE2 DATE2_str DATE2_fmt mm dd yy yyyy
ren date2 DATE2
save "D:\njmin\njmin_labeled.dta", replaceDATE2_str generated as str6
file D:\njmin\njmin_labeled.dta saved
3 Sample Design and Response Rates
3.1 Taking a look at the response rates
The following code creates a comprehensive summary of survey response patterns across all stores and by state. The analysis systematically calculates response rates and reasons for non-response to assess data quality and potential selection bias.
* Summary statistics
summarize
clear all
set more off
use njmin_labeled.dta
qui count
local all_stores = r(N)
qui count if STATUS2 == 1
local all_interviewed = r(N)
qui count if STATUS2 == 2
local all_renovations = r(N)
qui count if STATUS2 == 3
local all_closed = r(N)
qui count if STATUS2 == 4
local all_temp_closed = r(N)
qui count if STATUS2 == 5
local all_fire_closed = r(N)
qui count if STATUS2 == 0
local all_refused = r(N)
qui count if STATE == 0
local pa_stores = r(N)
qui count if STATE == 0 & STATUS2 == 1
local pa_interviewed = r(N)
qui count if STATE == 0 & STATUS2 == 2
local pa_renovations = r(N)
qui count if STATE == 0 & STATUS2 == 3
local pa_closed = r(N)
qui count if STATE == 0 & STATUS2 == 4
local pa_temp_closed = r(N)
qui count if STATE == 0 & STATUS2 == 5
local pa_fire_closed = r(N)
qui count if STATE == 0 & STATUS2 == 0
local pa_refused = r(N)
qui count if STATE == 1
local nj_stores = r(N)
qui count if STATE == 1 & STATUS2 == 1
local nj_interviewed = r(N)
qui count if STATE == 1 & STATUS2 == 2
local nj_renovations = r(N)
qui count if STATE == 1 & STATUS2 == 3
local nj_closed = r(N)
qui count if STATE == 1 & STATUS2 == 4
local nj_temp_closed = r(N)
qui count if STATE == 1 & STATUS2 == 5
local nj_fire_closed = r(N)
qui count if STATE == 1 & STATUS2 == 0
local nj_refused = r(N)
clear
set obs 7
gen Category = ""
gen All = .
gen PA = .
gen NJ = .
replace Category = "Num_stores" in 1
replace All = `all_stores' in 1
replace PA = `pa_stores' in 1
replace NJ = `nj_stores' in 1
replace Category = "Num_Interviewed" in 2
replace All = `all_interviewed' in 2
replace PA = `pa_interviewed' in 2
replace NJ = `nj_interviewed' in 2
replace Category = "Num_Renovations" in 3
replace All = `all_renovations' in 3
replace PA = `pa_renovations' in 3
replace NJ = `nj_renovations' in 3
replace Category = "Num_Closed" in 4
replace All = `all_closed' in 4
replace PA = `pa_closed' in 4
replace NJ = `nj_closed' in 4
replace Category = "Num_temp_closed" in 5
replace All = `all_temp_closed' in 5
replace PA = `pa_temp_closed' in 5
replace NJ = `nj_temp_closed' in 5
replace Category = "Num_Close_due_to_fire" in 6
replace All = `all_fire_closed' in 6
replace PA = `pa_fire_closed' in 6
replace NJ = `nj_fire_closed' in 6
replace Category = "Refused_Second_Interview" in 7
replace All = `all_refused' in 7
replace PA = `pa_refused' in 7
replace NJ = `nj_refused' in 7
list, clean noobs Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
SHEET | 410 246.5073 148.2318 1 522
CHAIN | 410 2.117073 1.110497 1 4
CO_OWNED | 410 .3439024 .4755893 0 1
STATE | 410 .8073171 .394888 0 1
SOUTHJ | 410 .2268293 .4192929 0 1
-------------+---------------------------------------------------------
CENTRALJ | 410 .1536585 .3610617 0 1
NORTHJ | 410 .4268293 .4952214 0 1
PA1 | 410 .0878049 .2833567 0 1
PA2 | 410 .104878 .3067706 0 1
SHORE | 410 .0853659 .2797667 0 1
-------------+---------------------------------------------------------
NCALLS | 410 1.141463 1.386095 0 8
EMPFT | 404 8.20297 8.619523 0 60
EMPPT | 406 18.83128 10.08173 0 60
NMGRS | 404 3.420297 1.018408 1 10
WAGE_ST | 390 4.615641 .3470151 4.25 5.75
-------------+---------------------------------------------------------
INCTIME | 379 18.31003 11.20461 2 52
FIRSTINC | 367 .2252861 .1079813 .05 .75
BONUS | 410 .2463415 .4314062 0 1
PCTAFF | 366 48.86967 35.11595 0 100
MEALS | 410 1.907317 .5336548 0 3
-------------+---------------------------------------------------------
OPEN | 410 8.041463 2.160885 0 11.5
HRSOPEN | 410 14.43902 2.809987 7 24
PSODA | 402 1.044876 .0886873 .73 1.49
PFRY | 393 .9219847 .1058813 .67 1.27
PENTREE | 398 1.322186 .6430845 .49 3.95
-------------+---------------------------------------------------------
NREGS | 404 3.594059 1.257657 1 8
NREGS11 | 398 2.71608 .8878087 1 6
TYPE2 | 410 1.095122 .2937417 1 2
STATUS2 | 410 1.04878 .3532053 0 5
NCALLS2 | 161 2.223602 1.76414 1 9
-------------+---------------------------------------------------------
EMPFT2 | 398 8.275126 7.970763 0 40
EMPPT2 | 400 18.6775 10.69964 0 60
NMGRS2 | 404 3.483911 1.139898 0 8
WAGE_ST2 | 389 4.996273 .2531905 4.25 6.25
INCTIME2 | 344 22.03198 12.8293 2 52
-------------+---------------------------------------------------------
FIRSTIN2 | 330 .2170909 .1057957 0 1
SPECIAL2 | 392 .2091837 .4072456 0 1
MEALS2 | 399 1.776942 .547144 0 3
OPEN2R | 399 8.110902 2.157961 0 11.5
HRSOPEN2 | 399 14.46554 2.752495 8 24
-------------+---------------------------------------------------------
PSODA2 | 388 1.044948 .093567 .41 1.4
PFRY2 | 382 .9412304 .1093037 .69 1.37
PENTREE2 | 386 1.354067 .6497019 .41 2.85
NREGS2 | 388 3.608247 1.24354 1 8
NREGS112 | 383 2.660574 .8860092 0 7
-------------+---------------------------------------------------------
DATE2 | 410 12007.52 21.42288 11637 12053
Number of observations (_N) was 0, now 7.
(7 missing values generated)
(7 missing values generated)
(7 missing values generated)
(7 missing values generated)
variable Category was str1 now str10
(1 real change made)
(1 real change made)
(1 real change made)
(1 real change made)
variable Category was str10 now str15
(1 real change made)
(1 real change made)
(1 real change made)
(1 real change made)
(1 real change made)
(1 real change made)
(1 real change made)
(1 real change made)
(1 real change made)
(1 real change made)
(1 real change made)
(1 real change made)
(1 real change made)
(1 real change made)
(1 real change made)
(1 real change made)
variable Category was str15 now str21
(1 real change made)
(1 real change made)
(1 real change made)
(1 real change made)
variable Category was str21 now str24
(1 real change made)
(1 real change made)
(1 real change made)
(1 real change made)
Category All PA NJ
Num_stores 410 79 331
Num_Interviewed 399 78 321
Num_Renovations 2 0 2
Num_Closed 6 1 5
Num_temp_closed 1 0 1
Num_Close_due_to_fire 1 0 1
Refused_Second_Interview 1 0 1
3.2 Tabulating our results in a LaTeX table.
The following code writes a .tex file generating Table-1
from the paper using the data we aggregated above.
tempname myfile
file open `myfile' using "table1.tex", write replace
file write `myfile' "\documentclass{article}" _n
file write `myfile' "\usepackage{booktabs}" _n
file write `myfile' "\begin{document}" _n _n
file write `myfile' "\begin{table}[htbp]" _n
file write `myfile' "\centering" _n
file write `myfile' "\caption{Store Status Summary}" _n
file write `myfile' "\label{tab:summary}" _n
file write `myfile' "\begin{tabular}{lccc}" _n
file write `myfile' "\toprule" _n
file write `myfile' "Category & All & PA & NJ \\" _n
file write `myfile' "\midrule" _n
file write `myfile' "Number of Stores & `all_stores' & `pa_stores' & `nj_stores' \\" _n
file write `myfile' "Interviewed & `all_interviewed' & `pa_interviewed' & `nj_interviewed' \\" _n
file write `myfile' "Renovations & `all_renovations' & `pa_renovations' & `nj_renovations' \\" _n
file write `myfile' "Closed & `all_closed' & `pa_closed' & `nj_closed' \\" _n
file write `myfile' "Temporarily Closed & `all_temp_closed' & `pa_temp_closed' & `nj_temp_closed' \\" _n
file write `myfile' "Closed Due to Fire & `all_fire_closed' & `pa_fire_closed' & `nj_fire_closed' \\" _n
file write `myfile' "Refused Interview & `all_refused' & `pa_refused' & `nj_refused' \\" _n
file write `myfile' "\bottomrule" _n
file write `myfile' "\end{tabular}" _n
file write `myfile' "\end{table}" _n
file write `myfile' "\end{document}" _n
file close `myfile'
di "LaTeX table successfully created: table1.tex"LaTeX table successfully created: table1.tex
In the public data the stores that dropped out after the first wave are no longer in the data set, making the table look a bit different from the one in the original paper.
We can see from the table above that out of 410 total stores surveyed (79 in Pennsylvania, 331 in New Jersey), 399 stores (97.3%) completed both interview waves, with only 1 store refusing the second interview. The minimal attrition consisting mainly of temporary closures for renovations (2 stores) and permanent closures (6 stores) appears random rather than systematic, reducing concerns about differential attrition bias between treatment and control groups. This ensures that the final sample is representative of fast-food establishments in both states and that any observed employment effects can be attributed to the minimum wage policy rather than survey-related selection bias.
4 Descriptive Statistics
4.1 Variable Construction and creating state-level summary statistics
The following section creates the key analytical variables used throughout the study. The code constructs employment measures (full-time equivalent employment), calculates percentage compositions, and creates categorical variables for different store types and geographic regions. These variables form the foundation for all subsequent descriptive and econometric analyses. Then we aggregate the individual store data to create state-level summary statistics.
use "D:\njmin\njmin_labeled.dta", clear
gen burger = (CHAIN == 1)
gen kfc = (CHAIN == 2)
gen roy = (CHAIN == 3)
gen wendy = (CHAIN == 4)
gen co_owned = (CO_OWNED == 1)
gen fte1 = EMPFT + NMGRS + 0.5*EMPPT
gen pct_full1 = (EMPFT + NMGRS)/(EMPFT + EMPPT + NMGRS) if !missing(EMPFT, EMPPT, NMGRS)
gen wage1 = WAGE_ST
gen wage_425_pct = PCTAFF // Percentage at $4.25
gen meal1 = PENTREE + PFRY + PSODA
gen hrs1 = HRSOPEN
gen fte2 = EMPFT2 + NMGRS2 + 0.5*EMPPT2
gen pct_full2 = (EMPFT2 + NMGRS2)/(EMPFT2 + EMPPT2 + NMGRS2) if !missing(EMPFT2, EMPPT2, NMGRS2)
gen wage2 = WAGE_ST2
gen meal2 = PENTREE2 + PFRY2 + PSODA2
gen hrs2 = HRSOPEN2
preserve
s
collapse (sum) burger kfc roy wendy co_owned (mean) fte1 pct_full1 wage1 wage_425_pct meal1 hrs1 fte2 pct_full2 wage2 meal2 hrs2, by(STATE)
foreach var of varlist burger-co_owned {
replace `var' = round(`var', 1) // Whole numbers for counts
}
foreach var of varlist fte* hrs* {
replace `var' = round(`var', 0.01)
}
replace pct_full1 = round(pct_full1, 0.01)
replace pct_full2 = round(pct_full2, 0.01)
replace wage_425_pct = round(wage_425_pct, 0.01)
foreach var of varlist wage* meal* {
replace `var' = round(`var', 0.01)
}
save "D:\njmin\table2_data.dta", replace
restore
* We should ideally be using preserve and restore here but StataMarkdown blocks seperately and we would lose our original dataset. In my STATA do-file, I use preserve and collect.(12 missing values generated)
(12 missing values generated)
(20 missing values generated)
(44 missing values generated)
(23 missing values generated)
(14 missing values generated)
(20 missing values generated)
(21 missing values generated)
(34 missing values generated)
(11 missing values generated)
command s is unrecognized
r(199);
r(199);
4.2 Tabulating our data in a LaTeX table
Just as before, the following code writes a .tex file
which generates Table-2 from the paper using the data from the above
block.
use "D:\njmin\table2_data.dta", clear
file open mytable using "table2.tex", write replace
file write mytable "\documentclass{article}" _n
file write mytable "\usepackage{booktabs} % For professional tables" _n
file write mytable "\usepackage{textcomp} % For currency symbols" _n
file write mytable "\begin{document}" _n _n
file write mytable "\setcounter{table}{1}" _n
file write mytable "\begin{table}[htbp]" _n
file write mytable "\centering" _n
file write mytable "\caption{Means of Key Variables}" _n
file write mytable "\label{tab:means}" _n _n
file write mytable "\begin{tabular}{lcc}" _n
file write mytable "\toprule" _n
file write mytable " & PA & NJ \\" _n
file write mytable "\midrule" _n
file write mytable "STATE & " %4.2f (STATE[1]) " & " %4.2f (STATE[2]) " \\" _n
file write mytable "\midrule" _n
file write mytable "\multicolumn{3}{l}{\textbf{1. Distribution of Store Types}} \\" _n
file write mytable "a. Burger King & " %5.2f (burger[1]) " & " %5.2f (burger[2]) " \\" _n
file write mytable "b. KFC & " %5.2f (kfc[1]) " & " %5.2f (kfc[2]) " \\" _n
file write mytable "c. Roy Rogers & " %5.2f (roy[1]) " & " %5.2f (roy[2]) " \\" _n
file write mytable "d. Wendys & " %5.2f (wendy[1]) " & " %5.2f (wendy[2]) " \\" _n
file write mytable "e. CompanyOwned & " %5.2f (co_owned[1]) " & " %5.2f (co_owned[2]) " \\" _n
file write mytable "\midrule" _n
file write mytable "\multicolumn{3}{l}{\textbf{2. Means in Wave 1:}} \\" _n
file write mytable "f. FTE Employment & " %5.2f (fte1[1]) " & " %5.2f (fte1[2]) " \\" _n
file write mytable "g. Percentage full-time employees & " %4.2f (pct_full1[1]) " & " %4.2f (pct_full1[2]) " \\" _n
file write mytable "h. Starting Wage & " %4.2f (wage1[1]) " & " %4.2f (wage1[2]) " \\" _n
file write mytable `"i. Wage = \textdollar 4.25 (percentage) & "' %5.2f (wage_425_pct[1]) `" & "' %5.2f (wage_425_pct[2]) " \\" _n
file write mytable "j. Price of full meal & " %4.2f (meal1[1]) " & " %4.2f (meal1[2]) " \\" _n
file write mytable "k. Hours open on week days & " %5.2f (hrs1[1]) " & " %5.2f (hrs1[2]) " \\" _n
file write mytable "\midrule" _n
file write mytable "\multicolumn{3}{l}{\textbf{3. Means in Wave 2:}} \\" _n
file write mytable "l. FTE Employment & " %5.2f (fte2[1]) " & " %5.2f (fte2[2]) " \\" _n
file write mytable "m. Percentage full-time employees & " %4.2f (pct_full2[1]) " & " %4.2f (pct_full2[2]) " \\" _n
file write mytable "n. Starting Wage & " %4.2f (wage2[1]) " & " %4.2f (wage2[2]) " \\" _n
file write mytable "o. Price of full meal & " %4.2f (meal2[1]) " & " %4.2f (meal2[2]) " \\" _n
file write mytable "p. Hours open on week days & " %5.2f (hrs2[1]) " & " %5.2f (hrs2[2]) " \\" _n
file write mytable "\bottomrule" _n
file write mytable "\end{tabular}" _n
file write mytable "\end{table}" _n
file write mytable "\end{document}" _n
file close mytable
display "Table successfully written to table2_formatted.tex"command s is unrecognized
r(199);
Table successfully written to table2_formatted.tex
Table 2 above presents descriptive statistics comparing fast-food restaurants in Pennsylvania (control) and New Jersey (treatment) before and after New Jersey’s minimum wage increase from $4.25 to $5.05 in April 1992. We see that the two states had remarkably similar fast-food labor markets in Wave 1 (February 1992), with comparable store compositions, employment levels, starting wages around $4.25, and other operational characteristics like meal prices and hours. This validates our parallel trends assumption, crucial for the difference-in-differences design, establishing that Pennsylvania serves as a credible control group for measuring the causal effects of New Jersey’s minimum wage policy. The Wave 2 data (November 1992) then shows the post-treatment outcomes, with New Jersey wages rising as expected due to the policy change, while the employment effects can be attributed to the minimum wage increase rather than pre-existing differences between states.
5 Wage Distribution
The following code replicates the wage distribution histograms from the paper,showing the starting wages at fast food restaurants in New Jersey and Pennsylvania before and after New Jersey’s minimum wage increase.
5.1 Wage Distribution on February, 1992
use njmin_labeled.dta, clear
tab STATE
summarize WAGE_ST if STATE == 0, detail
summarize WAGE_ST if STATE == 1, detail
tab WAGE_ST STATE, row
label define state_labels 0 "Pennsylvania" 1 "New Jersey"
label values STATE state_labels
summarize WAGE_ST
local range = r(max) - r(min)
local binwidth = `range' / 14
local start = r(min)
gen bin_num = floor((WAGE_ST - `start') / `binwidth')
replace bin_num = 13 if bin_num >= 14
gen bin_center = `start' + (bin_num + 0.5) * `binwidth'
egen total_sample = count(WAGE_ST)
bysort STATE bin_num: gen bin_count = _N
gen pct_of_total = (bin_count / total_sample) * 100
bysort STATE bin_num: keep if _n == 1
list STATE bin_center pct_of_total if bin_center > 4.9 & bin_center < 5.1, clean
gen x_left = bin_center - `binwidth'/4 if STATE == 0
gen x_right = bin_center + `binwidth'/4 if STATE == 1
twoway ///
(bar pct_of_total x_left if STATE == 0, barwidth(`=`binwidth'/2.2') color("black")) ///
(bar pct_of_total x_right if STATE == 1, barwidth(`=`binwidth'/2.2') color("gs10")), ///
legend(order(1 "Pennsylvania" 2 "New Jersey") pos(1) ring(0) cols(1) region(color(white))) ///
title("Distribution of Starting Wages, February 1992") ///
xtitle("Starting wage ($/hour)") ytitle("Percent of stores") ///
ylabel(0(5)30) xlabel(4(0.5)6) ///
graphregion(color(white)) plotregion(color(white)) ///
name(feb1992_overall, replace)
graph export "Feb_1992.jpg", as(jpg) quality(95) width(800) height(600) replacecommand s is unrecognized
r(199);
State: 1=New |
Jersey, |
0=Pennsylvan |
ia | Freq. Percent Cum.
-------------+-----------------------------------
Pennsylvania | 79 19.27 19.27
New Jersey | 331 80.73 100.00
-------------+-----------------------------------
Total | 410 100.00
Starting wage ($/hr, wave 1)
-------------------------------------------------------------
Percentiles Smallest
1% 4.25 4.25
5% 4.25 4.25
10% 4.25 4.25 Obs 76
25% 4.25 4.25 Sum of wgt. 76
50% 4.5 Mean 4.630132
Largest Std. dev. .3516873
75% 5 5.25
90% 5 5.25 Variance .123684
95% 5.25 5.5 Skewness .4187342
99% 5.5 5.5 Kurtosis 2.095706
Starting wage ($/hr, wave 1)
-------------------------------------------------------------
Percentiles Smallest
1% 4.25 4.25
5% 4.25 4.25
10% 4.25 4.25 Obs 314
25% 4.25 4.25 Sum of wgt. 314
50% 4.5 Mean 4.612134
Largest Std. dev. .3463505
75% 4.87 5.5
90% 5 5.56 Variance .1199587
95% 5.25 5.62 Skewness .7222411
99% 5.5 5.75 Kurtosis 2.8161
+----------------+
| Key |
|----------------|
| frequency |
| row percentage |
+----------------+
Starting |
wage | State: 1=New Jersey,
($/hr, | 0=Pennsylvania
wave 1) | Pennsylva New Jerse | Total
-----------+----------------------+----------
4.25 | 26 101 | 127
| 20.47 79.53 | 100.00
-----------+----------------------+----------
4.32 | 0 1 | 1
| 0.00 100.00 | 100.00
-----------+----------------------+----------
4.35 | 1 5 | 6
| 16.67 83.33 | 100.00
-----------+----------------------+----------
4.37 | 0 5 | 5
| 0.00 100.00 | 100.00
-----------+----------------------+----------
4.39 | 0 1 | 1
| 0.00 100.00 | 100.00
-----------+----------------------+----------
4.4 | 0 1 | 1
| 0.00 100.00 | 100.00
-----------+----------------------+----------
4.45 | 0 2 | 2
| 0.00 100.00 | 100.00
-----------+----------------------+----------
4.5 | 13 50 | 63
| 20.63 79.37 | 100.00
-----------+----------------------+----------
4.55 | 0 2 | 2
| 0.00 100.00 | 100.00
-----------+----------------------+----------
4.6 | 0 2 | 2
| 0.00 100.00 | 100.00
-----------+----------------------+----------
4.62 | 0 15 | 15
| 0.00 100.00 | 100.00
-----------+----------------------+----------
4.65 | 0 2 | 2
| 0.00 100.00 | 100.00
-----------+----------------------+----------
4.67 | 1 1 | 2
| 50.00 50.00 | 100.00
-----------+----------------------+----------
4.75 | 10 38 | 48
| 20.83 79.17 | 100.00
-----------+----------------------+----------
4.8 | 0 4 | 4
| 0.00 100.00 | 100.00
-----------+----------------------+----------
4.85 | 0 2 | 2
| 0.00 100.00 | 100.00
-----------+----------------------+----------
4.87 | 1 7 | 8
| 12.50 87.50 | 100.00
-----------+----------------------+----------
4.95 | 0 2 | 2
| 0.00 100.00 | 100.00
-----------+----------------------+----------
5 | 20 45 | 65
| 30.77 69.23 | 100.00
-----------+----------------------+----------
5.05 | 0 4 | 4
| 0.00 100.00 | 100.00
-----------+----------------------+----------
5.06 | 0 1 | 1
| 0.00 100.00 | 100.00
-----------+----------------------+----------
5.1 | 0 1 | 1
| 0.00 100.00 | 100.00
-----------+----------------------+----------
5.12 | 0 3 | 3
| 0.00 100.00 | 100.00
-----------+----------------------+----------
5.15 | 0 1 | 1
| 0.00 100.00 | 100.00
-----------+----------------------+----------
5.25 | 2 6 | 8
| 25.00 75.00 | 100.00
-----------+----------------------+----------
5.3 | 0 1 | 1
| 0.00 100.00 | 100.00
-----------+----------------------+----------
5.37 | 0 1 | 1
| 0.00 100.00 | 100.00
-----------+----------------------+----------
5.42 | 0 1 | 1
| 0.00 100.00 | 100.00
-----------+----------------------+----------
5.5 | 2 6 | 8
| 25.00 75.00 | 100.00
-----------+----------------------+----------
5.56 | 0 1 | 1
| 0.00 100.00 | 100.00
-----------+----------------------+----------
5.62 | 0 1 | 1
| 0.00 100.00 | 100.00
-----------+----------------------+----------
5.75 | 0 1 | 1
| 0.00 100.00 | 100.00
-----------+----------------------+----------
Total | 76 314 | 390
| 19.49 80.51 | 100.00
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
WAGE_ST | 390 4.615641 .3470151 4.25 5.75
(20 missing values generated)
(21 real changes made)
(387 observations deleted)
STATE bin_ce~r pct_of~l
6. Pennsylvania 5.053571 5.128205
16. New Jersey 4.946429 .5128205
17. New Jersey 5.053571 13.07692
(14 missing values generated)
(9 missing values generated)
file Feb_1992.jpg written in JPEG format
5.2 Wage Distribution on November. 1992
summarize WAGE_ST2
local range = r(max) - r(min)
local binwidth = `range' / 14
local start = r(min)
gen bin_num2 = floor((WAGE_ST2 - `start') / `binwidth')
replace bin_num2 = 13 if bin_num2 >= 14
gen bin_center2 = `start' + (bin_num2 + 0.5) * `binwidth'
egen total_sample2 = count(WAGE_ST2)
bysort STATE bin_num2: gen bin_count2 = _N
gen pct_of_total2 = (bin_count2 / total_sample2) * 100
bysort STATE bin_num2: keep if _n == 1
gen x_left2 = bin_center2 - `binwidth'/4 if STATE == 0
gen x_right2 = bin_center2 + `binwidth'/4 if STATE == 1
twoway ///
(bar pct_of_total2 x_left2 if STATE == 0, barwidth(`=`binwidth'/2.2') color("black")) ///
(bar pct_of_total2 x_right2 if STATE == 1, barwidth(`=`binwidth'/2.2') color("gs10")), ///
legend(order(1 "Pennsylvania" 2 "New Jersey") pos(1) ring(0) cols(1) region(color(white))) ///
title("Distribution of New Wages, November 1992") ///
xtitle("Wage in second wave ($/hour)") ytitle("Percent of stores") ///
ylabel(0(5)30) xlabel(4(0.5)6) ///
graphregion(color(white)) plotregion(color(white)) ///
name(nov1992_overall, replace)
graph export "Nov_1992.jpg", as(jpg) quality(95) width(800) height(600) replacecommand s is unrecognized
r(199);
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
WAGE_ST2 | 389 4.996273 .2531905 4.25 6.25
(21 missing values generated)
(22 real changes made)
(396 observations deleted)
(7 missing values generated)
(7 missing values generated)
file Nov_1992.jpg written in JPEG format
We see that in February 1992, both states show similar wage distributions, with most fast food restaurants paying starting wages clustered around the federal minimum wage of $4.25, showing that the two states had comparable labour market conditions leading up to policy intervention.
However, in November 1992, i.e post-treatment, for New Jersey we see that the wage distribution shifts dramatically rightward, with a spike at $5.05 (the new state minimum) and virtually no restaurants paying below this level. However, for Pennsylvania, age distribution remains largely unchanged, still centered around $4.25-$4.50.
6 Difference-in-Difference Estimation
6.1 Simple Comparison
In the following code, we report the difference-in-differences estimates comparing changes in full-time-equivalent employment at fast-food restaurants in New Jersey, where the minimum wage rose from $4.25 to $5.05, to those in Pennsylvania, where it did not change and then we write the computed data into a LaTeX file, tabulating our results.
use "njmin_labeled.dta", clear
gen fte_emp1 = EMPFT + NMGRS + 0.5 * EMPPT
gen fte_emp2 = EMPFT2 + NMGRS2 + 0.5 * EMPPT2
gen wage_cat = .
replace wage_cat = 1 if STATE == 1 & WAGE_ST == 4.25 // EXACTLY $4.25 stores (changed from < 4.26)
replace wage_cat = 2 if STATE == 1 & WAGE_ST >= 4.26 & WAGE_ST <= 4.99 // $4.26-$4.99 (added <= to match R's between())
replace wage_cat = 3 if STATE == 1 & WAGE_ST >= 5.00 // $5.00+
sum fte_emp1 if STATE == 0
local pa_emp1 = r(mean)
sum fte_emp1 if STATE == 1
local nj_emp1 = r(mean)
sum fte_emp2 if STATE == 0
local pa_emp2 = r(mean)
sum fte_emp2 if STATE == 1
local nj_emp2 = r(mean)
sum fte_emp1 if STATE == 1 & WAGE_ST == 4.25 // Changed from wage_cat == 1
local nj425_emp1 = r(mean)
sum fte_emp1 if STATE == 1 & WAGE_ST >= 4.26 & WAGE_ST <= 4.99 // Changed from wage_cat == 2
local nj426499_emp1 = r(mean)
sum fte_emp1 if STATE == 1 & WAGE_ST >= 5.00 // Changed from wage_cat == 3
local nj500_emp1 = r(mean)
sum fte_emp2 if STATE == 1 & WAGE_ST == 4.25 // Changed from wage_cat == 1
local nj425_emp2 = r(mean)
sum fte_emp2 if STATE == 1 & WAGE_ST >= 4.26 & WAGE_ST <= 4.99 // Changed from wage_cat == 2
local nj426499_emp2 = r(mean)
sum fte_emp2 if STATE == 1 & WAGE_ST >= 5.00 // Changed from wage_cat == 3
local nj500_emp2 = r(mean)
local pa_nj_diff1 = `pa_emp1' - `nj_emp1'
local pa_nj_diff2 = `pa_emp2' - `nj_emp2'
local nj425_500_diff1 = `nj425_emp1' - `nj500_emp1'
local nj426499_500_diff1 = `nj426499_emp1' - `nj500_emp1'
local nj425_500_diff2 = `nj425_emp2' - `nj500_emp2'
local nj426499_500_diff2 = `nj426499_emp2' - `nj500_emp2'
local pa_change = `pa_emp2' - `pa_emp1'
local nj_change = `nj_emp2' - `nj_emp1'
local nj425_change = `nj425_emp2' - `nj425_emp1'
local nj426499_change = `nj426499_emp2' - `nj426499_emp1'
local nj500_change = `nj500_emp2' - `nj500_emp1'
local diff_nj_pa_calc = `nj_change' - `pa_change'
local low_high_diff_calc = `nj425_change' - `nj500_change'
local mid_high_diff_calc = `nj426499_change' - `nj500_change'
display "PA Employment Wave 1: " `pa_emp1'
display "PA Employment Wave 2: " `pa_emp2'
display "PA Change: " `pa_change'
display "NJ Employment Wave 1: " `nj_emp1'
display "NJ Employment Wave 2: " `nj_emp2'
display "NJ Change: " `nj_change'
display "NJ-PA Difference in Changes: " `diff_nj_pa_calc'
display "NJ $4.25 stores change: " `nj425_change'
display "NJ $5.00+ stores change: " `nj500_change'
display "Low-High difference: " `low_high_diff_calc'
file open mytable using "table3.tex", write replace
file write mytable "\documentclass{article}" _n
file write mytable "\usepackage{booktabs}" _n
file write mytable "\usepackage{multirow}" _n
file write mytable "\usepackage{array}" _n
file write mytable "\usepackage{adjustbox}" _n
file write mytable "\begin{document}" _n _n
file write mytable "\setcounter{table}{2}" _n
file write mytable "\begin{table}[htbp]" _n
file write mytable "\centering" _n
file write mytable "\caption{AVERAGE EMPLOYMENT PER STORE BEFORE AND AFTER THE RISE IN NEW JERSEY MINIMUM WAGE}" _n
file write mytable "\label{tab:employment}" _n
file write mytable "\begin{adjustbox}{width=\textwidth,center}" _n
file write mytable "\begin{tabular}{lcccccccc}" _n
file write mytable "\toprule" _n
file write mytable " & \multicolumn{3}{c}{Stores by State} & \multicolumn{3}{c}{Stores in New Jersey} & \multicolumn{2}{c}{Differences within NJ} \\\\" _n
file write mytable "\cmidrule(r){2-4} \cmidrule(lr){5-7} \cmidrule(l){8-9}" _n
file write mytable " & PA (i) & NJ (ii) & Diff (iii) & \\\$4.25 (iv) & \\\$4.26-4.99 (v) & \\\$5.00 (vi) & Low-High (vii) & Mid-High (viii) \\\\" _n
file write mytable "\midrule" _n
file write mytable "FTE EMP1 & " %5.2f (`pa_emp1') " & " %5.2f (`nj_emp1') " & " %5.2f (`pa_nj_diff1') " & " %5.2f (`nj425_emp1') " & " %5.2f (`nj426499_emp1') " & " %5.2f (`nj500_emp1') " & " %5.2f (`nj425_500_diff1') " & " %5.2f (`nj426499_500_diff1') " \\\\" _n
file write mytable "FTE EMP2 & " %5.2f (`pa_emp2') " & " %5.2f (`nj_emp2') " & " %5.2f (`pa_nj_diff2') " & " %5.2f (`nj425_emp2') " & " %5.2f (`nj426499_emp2') " & " %5.2f (`nj500_emp2') " & " %5.2f (`nj425_500_diff2') " & " %5.2f (`nj426499_500_diff2') " \\\\" _n
file write mytable "Change & " %5.2f (`pa_change') " & " %5.2f (`nj_change') " & " %5.2f (`diff_nj_pa_calc') " & " %5.2f (`nj425_change') " & " %5.2f (`nj426499_change') " & " %5.2f (`nj500_change') " & " %5.2f (`low_high_diff_calc') " & " %5.2f (`mid_high_diff_calc') " \\\\" _n
file write mytable "\bottomrule" _n
file write mytable "\end{tabular}" _n
file write mytable "\end{adjustbox}" _n
file write mytable "\end{table}" _n
file write mytable "\end{document}" _n
file close mytable
display "Table 3 LaTeX file created: table3.tex"command s is unrecognized
r(199);
(12 missing values generated)
(14 missing values generated)
(410 missing values generated)
(101 real changes made)
(140 real changes made)
(90 real changes made)
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
fte_emp1 | 77 23.33117 11.85628 7.5 70.5
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
fte_emp1 | 321 20.43941 9.106239 5 85
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
fte_emp2 | 77 21.16558 8.276732 0 43.5
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
fte_emp2 | 319 21.02743 9.293024 0 60.5
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
fte_emp1 | 97 19.5567 7.631444 6 41.5
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
fte_emp1 | 137 20.08066 9.846855 5 85
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
fte_emp1 | 87 21.98851 9.311151 5 48
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
fte_emp2 | 98 20.87755 9.957917 0 60.5
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
fte_emp2 | 135 20.95556 8.779368 0 59
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
fte_emp2 | 86 21.31105 9.397038 0 53
PA Employment Wave 1: 23.331169
PA Employment Wave 2: 21.165584
PA Change: -2.1655844
NJ Employment Wave 1: 20.439408
NJ Employment Wave 2: 21.027429
NJ Change: .58802137
NJ-PA Difference in Changes: 2.7536058
NJ $4.25 stores change: 1.32085
NJ $5.00+ stores change: -.67745924
Low-High difference: 1.9983092
Table 3 LaTeX file created: table3.tex
Table 3 shows the average
full-time-equivalent (FTE) employment per store before (EMP1) and after
(EMP2) the April 1992 minimum wage increase in New Jersey, comparing New
Jersey to Pennsylvania and breaking NJ stores into wage categories.
Pennsylvania stores saw a drop of 2.17 FTEs, while New Jersey stores had
a small gain of 0.59 FTEs, yielding a difference-in-differences of
+2.75, indicating higher relative employment growth in NJ despite the
wage hike. Within NJ, stores that initially paid below $5.00—especially
those in the lowest wage group—tended to show larger employment
increases than higher-wage stores, reinforcing that the policy did not
reduce employment and may have modestly boosted it in the most affected
outlets.
An issue with this table is the slight discrepancy surrounding column (vi), which leads the outcomes from columns (vii) and (viii) from being slightly off the mark as well. I’m not quite sure why this is the case.
Nevertheless, to ensure that this issue isn’t stemming from our data getting corrupted from the previous steps before proceeding with our regression analysis, I used the same dataset on R to generate the same table. And the results come out perfectly.
library(haven)
library(dplyr)
library(kableExtra)
df <- read_dta("D:/njmin/njmin_labeled.dta")
stores_by_state <- df |>
group_by(STATE)|>
summarise(FTE_EMP1 = mean(EMPFT + NMGRS + .5 * EMPPT, na.rm = TRUE),
FTE_EMP2 = mean(EMPFT2 + NMGRS2 + .5 * EMPPT, na.rm = TRUE),
Change_in_mean_FTE = FTE_EMP2 - FTE_EMP1)|>
select(FTE_EMP1,FTE_EMP2,Change_in_mean_FTE) |>
mutate(across(everything(), ~ round(., 2)))
# transpose data
stores_by_state <- as.data.frame(t(stores_by_state))
# rename columns for table
stores_by_state <- stores_by_state |>
rename(`PA (i)` = V1,
`NJ (ii)` = V2) |>
mutate(`Diffrence in NJ - PA (iii)` = `NJ (ii)` - `PA (i)`)
# Column iv
stores_NJ_iv <- df |>
filter(STATE == 1 & WAGE_ST == 4.25 ) |>
summarise(FTE_EMP1 = mean(EMPFT + NMGRS + .5 * EMPPT, na.rm = TRUE),
FTE_EMP2 = mean(EMPFT2 + NMGRS2 + .5 * EMPPT, na.rm = TRUE),
Change_in_mean_FTE = FTE_EMP2 - FTE_EMP1)|>
select(FTE_EMP1,FTE_EMP2,Change_in_mean_FTE) |>
mutate(across(everything(), ~ round(., 2)))
# Column V
stores_NJ_v <- df |>
filter(STATE == 1 & between(WAGE_ST, 4.26,4.99)) |>
summarise(FTE_EMP1 = mean(EMPFT + NMGRS + .5 * EMPPT, na.rm = TRUE),
FTE_EMP2 = mean(EMPFT2 + NMGRS2 + .5 * EMPPT, na.rm = TRUE),
Change_in_mean_FTE = FTE_EMP2 - FTE_EMP1)|>
select(FTE_EMP1,FTE_EMP2,Change_in_mean_FTE) |>
mutate(across(everything(), ~ round(., 2)))
# Column vi
stores_NJ_vi <- df |>
filter(STATE == 1 & WAGE_ST >= 5) |>
summarise(FTE_EMP1 = mean(EMPFT + NMGRS + .5 * EMPPT, na.rm = TRUE),
FTE_EMP2 = mean(EMPFT2 + NMGRS2 + .5 * EMPPT, na.rm = TRUE),
Change_in_mean_FTE = FTE_EMP2 - FTE_EMP1)|>
select(FTE_EMP1,FTE_EMP2,Change_in_mean_FTE) |>
mutate(across(everything(), ~ round(., 2)))
# transpose Data
stores_NJ <- as.data.frame(t(rbind(stores_NJ_iv, stores_NJ_v, stores_NJ_vi)))
# rename columns for table
stores_NJ <- stores_NJ |>
rename(`Wage = $4.25 (iv)` = V1,
`Wage = $4.26-$4.99 (v)`= V2,
`Wage = $5.00 (vi)` = V3)
# colum vii
columnVII <- df |>
filter(STATE == 1) |>
summarise(FTEMP1_low = mean(ifelse(WAGE_ST == 4.25, EMPFT + NMGRS + .5 *
EMPPT, NA_real_), na.rm = TRUE),
FTEMP1_high = mean(ifelse(WAGE_ST >= 5 , EMPFT + NMGRS + .5 *
EMPPT, NA_real_), na.rm = TRUE),
`low-high FTE Before` = FTEMP1_low - FTEMP1_high,
FTEMP2_low = mean(ifelse(WAGE_ST == 4.25, EMPFT2 + NMGRS2 + .5 *
EMPPT2, NA_real_), na.rm = TRUE),
FTEMP2_high = mean(ifelse(WAGE_ST >= 5 , EMPFT2 + NMGRS2 + .5 *
EMPPT2, NA_real_), na.rm = TRUE),
`low-high FTE After` = FTEMP2_low - FTEMP2_high,
`Change in mean FTE` = `low-high FTE After` -`low-high FTE Before`
) |>
select(`low-high FTE Before`, `low-high FTE After`, `Change in mean FTE`) |>
rename( FTE_EMP1 = `low-high FTE Before`,
FTE_EMP2 = `low-high FTE After`,
Change_in_mean_FTE = `Change in mean FTE` )
# colum viii
columnVIII <- df |>
filter(STATE == 1) |>
summarise(FTEMP1_mid = mean(ifelse(between(WAGE_ST, 4.26,4.99),
EMPFT + NMGRS + .5 *EMPPT,
NA_real_), na.rm = TRUE),
FTEMP1_high = mean(ifelse(WAGE_ST >= 5 , EMPFT + NMGRS + .5 *
EMPPT, NA_real_), na.rm = TRUE),
`mid-high FTE Before` = FTEMP1_mid - FTEMP1_high,
FTEMP2_mid = mean(ifelse(between(WAGE_ST, 4.26,4.99),
EMPFT2 + NMGRS2 + .5 *EMPPT2,
NA_real_), na.rm = TRUE),
FTEMP2_high = mean(ifelse(WAGE_ST >= 5 ,
EMPFT2 + NMGRS2 + .5 *EMPPT2,
NA_real_), na.rm = TRUE),
`mid-high FTE After` = FTEMP2_mid - FTEMP2_high,
`Change in mean FTE` = `mid-high FTE After` -`mid-high FTE Before`
) |>
select(`mid-high FTE Before`, `mid-high FTE After`, `Change in mean FTE`) |>
rename( FTE_EMP1 = `mid-high FTE Before`,
FTE_EMP2 = `mid-high FTE After`,
Change_in_mean_FTE = `Change in mean FTE` )
Diffrence_NJ <- as.data.frame(t(rbind(columnVII, columnVIII)))
Diffrence_NJ <- Diffrence_NJ |>
rename(`Low-High (vii)` = V1,
`Mid-High (viii)` = V2)
# combine data frames for table
table3 <- cbind(stores_by_state, stores_NJ, Diffrence_NJ )
# using Kable for making the table look similar to above
kable(table3, caption = "Table 3 - AVERAGE EMPLOYMENT PER STORE BEFORE AND
AFTER THE RISE IN NEW JERSEY MINIMUM MAGE") |>
kable_classic(full_width = F, html_font = "Cambria") |>
add_header_above(c(" ","Stores by State" = 3,"Stores in New Jersey" = 3,
"Differences within NJ" = 2))|
Stores by State
|
Stores in New Jersey
|
Differences within NJ
|
||||||
|---|---|---|---|---|---|---|---|---|
| PA (i) | NJ (ii) | Diffrence in NJ - PA (iii) | Wage = $4.25 (iv) | Wage = $4.26-$4.99 (v) | Wage = $5.00 (vi) | Low-High (vii) | Mid-High (viii) | |
| FTE_EMP1 | 23.33 | 20.44 | -2.89 | 19.56 | 20.08 | 22.25 | -2.6932990 | -2.1693431 |
| FTE_EMP2 | 20.89 | 21.31 | 0.42 | 21.18 | 21.32 | 20.29 | 0.6637829 | 0.7417874 |
| Change_in_mean_FTE | -2.44 | 0.87 | 3.31 | 1.63 | 1.24 | -1.96 | 3.3570819 | 2.9111305 |
6.2 Regression Analysis
In the following section, we explore 5 different specifications:
- Basic State Comparison: \[\begin{aligned} \Delta \text{ Employment} &= \beta_0 + \beta_1 NJ + \varepsilon \end{aligned}\]
Tests mean employment change difference between NJ and PA.
- With Chain Controls: \[\begin{aligned} \Delta \text{ Employment} &= \beta_0 + \beta_1 NJ + \gamma_1 \text{ Chain } 1 + \gamma_2 \text{ Chain } 2 \\ &\quad + \gamma_3 \text{ Chain } 3 + \gamma_4 CO\_OWNED + \varepsilon \end{aligned}\]
Controls for chain affiliation and ownership status.
- Gap Model: \[\begin{aligned} \Delta \text{ Employment} &= \beta_0 + \beta_1 GAP + \varepsilon \end{aligned}\]
Uses wage gap as a continuous measure of treatment intensity.
Gap with Controls: \[\begin{aligned} \Delta \text{ Employment} &= \beta_0 + \beta_1 GAP + \gamma_1 \text{ Chain } 1 + \gamma_2 \text{ Chain } 2 \\ &\quad + \gamma_3 \text{ Chain } 3 + \gamma_4 CO\_OWNED + \varepsilon \end{aligned}\] Adds chain and ownership controls to the gap specification.
Regional Controls: \[\begin{aligned} \Delta Employment &= \beta_0 + \beta_1 GAP + \delta_1 SOUTHJ + \delta_2 CENTRALJ \\ &\quad + \delta_3 NORTHJ + \delta_4 PA1 + \delta_5 PA2 + \varepsilon \end{aligned}\]
Controls for geographic regions across NJ and PA.
Here, GAP is an alternative measure of the impact of the minimum wage at store based on the initial wage at that store:
\[ \begin{aligned} &\begin{aligned} \mathrm{GAP}_i & =0 \quad \text { for stores in Pennsylvania } \\ & =0 \quad \text { for stores in New Jersey with } \\ & \quad W_{1 i} \geq \$ 5.05 \\ & =\left(5.05-W_{1 i}\right) / W_{1 i} \end{aligned}\\ &\text { for other stores in New Jersey. } \end{aligned} \]
We end our analysis by generating a regression table aggregating our results as a LaTeX formatted table.
gen FTE_EMP1 = EMPFT + NMGRS + 0.5 * EMPPT
gen FTE_EMP2 = EMPFT2 + NMGRS2 + 0.5 * EMPPT2
gen delta_emp = FTE_EMP2 - FTE_EMP1
gen GAP = cond(STATE == 1 & WAGE_ST <= 5.05, (5.05 - WAGE_ST)/WAGE_ST, 0)
gen CHAIN1 = (CHAIN == 1)
gen CHAIN2 = (CHAIN == 2)
gen CHAIN3 = (CHAIN == 3)
summarize GAP if GAP > 0
reg delta_emp STATE, robust
estimates store reg1
reg delta_emp STATE CHAIN1 CHAIN2 CHAIN3 CO_OWNED, robust
estimates store reg2
reg delta_emp GAP, robust
estimates store reg3
reg delta_emp GAP CHAIN1 CHAIN2 CHAIN3 CO_OWNED, robust
estimates store reg4
reg delta_emp GAP SOUTHJ CENTRALJ NORTHJ PA1 PA2, robust
estimates store reg5
tempname myfile
file open `myfile' using "regression_table.tex", write replace
file write `myfile' "\documentclass{article}" _n
file write `myfile' "\usepackage{booktabs}" _n
file write `myfile' "\begin{document}" _n _n
file write `myfile' "\setcounter{table}{3}" _n
file write `myfile' "\begin{table}[htbp]" _n
file write `myfile' "\centering" _n
file write `myfile' "\caption{Employment Effects of Minimum Wage Changes}" _n
file write `myfile' "\begin{tabular}{lccccc}" _n
file write `myfile' "\toprule" _n
file write `myfile' " & \multicolumn{5}{c}{Dependent variable:} \\" _n
file write `myfile' "\cmidrule(lr){2-6}" _n
file write `myfile' " & \multicolumn{5}{c}{delta\_emp} \\" _n
file write `myfile' " & (1) & (2) & (3) & (4) & (5) \\" _n
file write `myfile' "\midrule" _n
local varlist STATE CHAIN1 CHAIN2 CHAIN3 CO_OWNED GAP SOUTHJ CENTRALJ NORTHJ PA1 PA2
foreach var in `varlist' {
* Clean variable names
if "`var'" == "CO_OWNED" local varname "Co-Owned"
else if "`var'" == "SOUTHJ" local varname "South Jersey"
else if "`var'" == "CENTRALJ" local varname "Central Jersey"
else if "`var'" == "NORTHJ" local varname "North Jersey"
else local varname "`var'"
file write `myfile' "`varname' "
* Coefficients
forval i = 1/5 {
estimates restore reg`i'
capture matrix list e(b)
if _rc == 0 {
matrix b = e(b)
capture local bval = b[1, "`var'"]
if _rc == 0 {
matrix V = e(V)
local seval = sqrt(V["`var'","`var'"])
local tval = `bval'/`seval'
local stars = ""
if abs(`tval') > invnormal(0.995) local stars "***"
else if abs(`tval') > invnormal(0.975) local stars "**"
else if abs(`tval') > invnormal(0.95) local stars "*"
file write `myfile' "& `: disp %6.3f `bval''`stars' "
}
else {
file write `myfile' "& "
}
}
else {
file write `myfile' "& "
}
}
file write `myfile' "\\" _n
* Standard errors
file write `myfile' " "
forval i = 1/5 {
estimates restore reg`i'
capture matrix list e(b)
if _rc == 0 {
matrix b = e(b)
capture local bval = b[1, "`var'"]
if _rc == 0 {
matrix V = e(V)
local seval = sqrt(V["`var'","`var'"])
file write `myfile' "& (`: disp %6.3f `seval'') "
}
else {
file write `myfile' "& "
}
}
else {
file write `myfile' "& "
}
}
file write `myfile' "\\" _n
}
* Constant at bottom
file write `myfile' "Constant "
forval i = 1/5 {
estimates restore reg`i'
matrix b = e(b)
local bval = b[1, "_cons"]
local seval = sqrt(e(V)["_cons","_cons"])
local tval = `bval'/`seval'
local stars = ""
if abs(`tval') > invnormal(0.995) local stars "***"
else if abs(`tval') > invnormal(0.975) local stars "**"
else if abs(`tval') > invnormal(0.95) local stars "*"
file write `myfile' "& `: disp %6.3f `bval''`stars' "
}
file write `myfile' "\\" _n
file write `myfile' " "
forval i = 1/5 {
estimates restore reg`i'
local seval = sqrt(e(V)["_cons","_cons"])
file write `myfile' "& (`: disp %6.3f `seval'') "
}
file write `myfile' "\\" _n
* Statistics
file write `myfile' "\midrule" _n
file write `myfile' "Observations "
forval i = 1/5 {
estimates restore reg`i'
file write `myfile' "& `: disp %9.0f e(N)' "
}
file write `myfile' "\\" _n
file write `myfile' "R\textsuperscript{2} "
forval i = 1/5 {
estimates restore reg`i'
file write `myfile' "& `: disp %5.3f e(r2)' "
}
file write `myfile' "\\" _n
* Close table
file write `myfile' "\bottomrule" _n
file write `myfile' "\end{tabular}" _n
file write `myfile' "\end{table}" _n
file write `myfile' "\end{document}" _n
file close `myfile'
di "LaTeX table successfully generated: regression_table.tex"command s is unrecognized
r(199);
(12 missing values generated)
(14 missing values generated)
(26 missing values generated)
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
GAP | 286 .1151997 .0666319 .01 .1882353
Linear regression Number of obs = 384
F(1, 382) = 4.23
Prob > F = 0.0405
R-squared = 0.0146
Root MSE = 8.9678
------------------------------------------------------------------------------
| Robust
delta_emp | Coefficient std. err. t P>|t| [95% conf. interval]
-------------+----------------------------------------------------------------
STATE | 2.75 1.337725 2.06 0.040 .1197732 5.380227
_cons | -2.283333 1.24814 -1.83 0.068 -4.737419 .1707523
------------------------------------------------------------------------------
Linear regression Number of obs = 384
F(5, 378) = 2.63
Prob > F = 0.0234
R-squared = 0.0290
Root MSE = 8.949
------------------------------------------------------------------------------
| Robust
delta_emp | Coefficient std. err. t P>|t| [95% conf. interval]
-------------+----------------------------------------------------------------
STATE | 2.784585 1.341441 2.08 0.039 .1469643 5.422207
CHAIN1 | .1910069 1.705447 0.11 0.911 -3.162345 3.544359
CHAIN2 | .4317933 1.635702 0.26 0.792 -2.784421 3.648007
CHAIN3 | -2.397383 1.685426 -1.42 0.156 -5.711368 .9166022
CO_OWNED | .362528 .8945692 0.41 0.686 -1.396427 2.121483
_cons | -2.018733 1.777929 -1.14 0.257 -5.514604 1.477138
------------------------------------------------------------------------------
Linear regression Number of obs = 384
F(1, 382) = 4.31
Prob > F = 0.0386
R-squared = 0.0113
Root MSE = 8.983
------------------------------------------------------------------------------
| Robust
delta_emp | Coefficient std. err. t P>|t| [95% conf. interval]
-------------+----------------------------------------------------------------
GAP | 12.48935 6.01802 2.08 0.039 .6567598 24.32194
_cons | -1.074889 .7458786 -1.44 0.150 -2.541431 .3916525
------------------------------------------------------------------------------
Linear regression Number of obs = 384
F(5, 378) = 2.54
Prob > F = 0.0283
R-squared = 0.0240
Root MSE = 8.9723
------------------------------------------------------------------------------
| Robust
delta_emp | Coefficient std. err. t P>|t| [95% conf. interval]
-------------+----------------------------------------------------------------
GAP | 11.91762 6.212361 1.92 0.056 -.297498 24.13273
CHAIN1 | -.1907231 1.745997 -0.11 0.913 -3.623806 3.24236
CHAIN2 | .169252 1.645526 0.10 0.918 -3.06628 3.404784
CHAIN3 | -2.52958 1.689472 -1.50 0.135 -5.85152 .7923592
CO_OWNED | .4082703 .9103216 0.45 0.654 -1.381658 2.198199
_cons | -.5080059 1.56346 -0.32 0.745 -3.582175 2.566163
------------------------------------------------------------------------------
note: PA2 omitted because of collinearity.
Linear regression Number of obs = 384
F(5, 378) = 2.16
Prob > F = 0.0578
R-squared = 0.0249
Root MSE = 8.968
------------------------------------------------------------------------------
| Robust
delta_emp | Coefficient std. err. t P>|t| [95% conf. interval]
-------------+----------------------------------------------------------------
GAP | 6.984181 6.882555 1.01 0.311 -6.548709 20.51707
SOUTHJ | .9092582 2.149188 0.42 0.672 -3.316603 5.13512
CENTRALJ | -.3328065 2.404856 -0.14 0.890 -5.061378 4.395765
NORTHJ | 1.02757 2.203378 0.47 0.641 -3.304844 5.359983
PA1 | -2.898135 2.418042 -1.20 0.231 -7.652634 1.856364
PA2 | 0 (omitted)
_cons | -.9695122 1.921319 -0.50 0.614 -4.747325 2.808301
------------------------------------------------------------------------------
(results reg1 are active now)
(results reg2 are active now)
(results reg3 are active now)
(results reg4 are active now)
(results reg5 are active now)
(results reg1 are active now)
(results reg2 are active now)
(results reg3 are active now)
(results reg4 are active now)
(results reg5 are active now)
(results reg1 are active now)
(results reg2 are active now)
(results reg3 are active now)
(results reg4 are active now)
(results reg5 are active now)
(results reg1 are active now)
(results reg2 are active now)
(results reg3 are active now)
(results reg4 are active now)
(results reg5 are active now)
(results reg1 are active now)
(results reg2 are active now)
(results reg3 are active now)
(results reg4 are active now)
(results reg5 are active now)
(results reg1 are active now)
(results reg2 are active now)
(results reg3 are active now)
(results reg4 are active now)
(results reg5 are active now)
(results reg1 are active now)
(results reg2 are active now)
(results reg3 are active now)
(results reg4 are active now)
(results reg5 are active now)
(results reg1 are active now)
(results reg2 are active now)
(results reg3 are active now)
(results reg4 are active now)
(results reg5 are active now)
(results reg1 are active now)
(results reg2 are active now)
(results reg3 are active now)
(results reg4 are active now)
(results reg5 are active now)
(results reg1 are active now)
(results reg2 are active now)
(results reg3 are active now)
(results reg4 are active now)
(results reg5 are active now)
(results reg1 are active now)
(results reg2 are active now)
(results reg3 are active now)
(results reg4 are active now)
(results reg5 are active now)
(results reg1 are active now)
(results reg2 are active now)
(results reg3 are active now)
(results reg4 are active now)
(results reg5 are active now)
(results reg1 are active now)
(results reg2 are active now)
(results reg3 are active now)
(results reg4 are active now)
(results reg5 are active now)
(results reg1 are active now)
(results reg2 are active now)
(results reg3 are active now)
(results reg4 are active now)
(results reg5 are active now)
(results reg1 are active now)
(results reg2 are active now)
(results reg3 are active now)
(results reg4 are active now)
(results reg5 are active now)
(results reg1 are active now)
(results reg2 are active now)
(results reg3 are active now)
(results reg4 are active now)
(results reg5 are active now)
(results reg1 are active now)
(results reg2 are active now)
(results reg3 are active now)
(results reg4 are active now)
(results reg5 are active now)
(results reg1 are active now)
(results reg2 are active now)
(results reg3 are active now)
(results reg4 are active now)
(results reg5 are active now)
(results reg1 are active now)
(results reg2 are active now)
(results reg3 are active now)
(results reg4 are active now)
(results reg5 are active now)
(results reg1 are active now)
(results reg2 are active now)
(results reg3 are active now)
(results reg4 are active now)
(results reg5 are active now)
(results reg1 are active now)
(results reg2 are active now)
(results reg3 are active now)
(results reg4 are active now)
(results reg5 are active now)
(results reg1 are active now)
(results reg2 are active now)
(results reg3 are active now)
(results reg4 are active now)
(results reg5 are active now)
(results reg1 are active now)
(results reg2 are active now)
(results reg3 are active now)
(results reg4 are active now)
(results reg5 are active now)
(results reg1 are active now)
(results reg2 are active now)
(results reg3 are active now)
(results reg4 are active now)
(results reg5 are active now)
(results reg1 are active now)
(results reg2 are active now)
(results reg3 are active now)
(results reg4 are active now)
(results reg5 are active now)
(results reg1 are active now)
(results reg2 are active now)
(results reg3 are active now)
(results reg4 are active now)
(results reg5 are active now)
LaTeX table successfully generated: regression_table.tex
Overall. we see that our results support the authors’ finding that minimum wage increases can have neutral or even positive employment effects. The STATE coefficient shows a significant positive employment effect from the minimum wage increase, while the significant GAP effects also replicate their finding that stores with larger wage gaps (those most affected) showed greater employment increases. We also see that chain effects are mixed and mostly insignificant, suggesting the impact varies across different restaurant chains.
The low R² values (0.011-0.029) suggest other factors explain most employment variation, which is typical for this type of natural experiment and consistent with the original study’s findings.
7 References
Card, D., & Krueger, A. B. (1994). Minimum wages and employment: A case study of the fast-food industry in New Jersey and Pennsylvania. American Economic Review, 84(4), 772-793.