
Stata Accounting Research
- 52 installs
- 3.2k repo stars
- Updated August 4, 2026
- brycewang-stanford/awesome-agent-skills-for-empirical-research
stata-accounting-research is a Claude skill that provides Stata syntax patterns from 126 peer-reviewed Journal of Accounting Research replication files for empirical accounting research.
About
A skill providing Stata syntax patterns drawn from 126 peer-reviewed Journal of Accounting Research replication files spanning 2017-2025. Accounting researchers use it to look up how published papers implemented methods like difference-in-differences, event studies, and entropy balancing, then adapt the code to their own variable names. It provides code patterns with source citations but not research-design or identification advice.
- STATA syntax patterns from 126 peer-reviewed JAR replication files (2017-2025)
- Covers panel fixed effects, DiD, event studies, PSM, and entropy balancing
- Provides multiple published implementations of the same method with source citations
Stata Accounting Research by the numbers
- 52 all-time installs (skills.sh)
- Ranked #921 of 2,064 Data Science & ML skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
stata-accounting-research capabilities & compatibility
- Capabilities
- regression modeling · causal inference
- Use cases
- data analysis · research
What stata-accounting-research says it does
A Claude Code skill providing STATA syntax patterns from 126 peer-reviewed JAR replication files (2017-2025).
This skill includes only STATA .do files. Other file types (SAS, R, Python, data files) from the original replication packages are not included.
The .do files are sourced from the Journal of Accounting Research Online Supplements:
npx skills add https://github.com/brycewang-stanford/awesome-agent-skills-for-empirical-research --skill stata-accounting-researchAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 52 |
|---|---|
| repo stars | ★ 3.2k |
| Last updated | August 4, 2026 |
| Repository | brycewang-stanford/awesome-agent-skills-for-empirical-research ↗ |
What it does
Look up Stata syntax patterns from published accounting-research papers and adapt them to your variable names.
Who is it for?
Finding published Stata implementations of econometric methods in accounting research.
Skip if: Research design, identification strategy, or methodological trade-off advice.
When should I use this skill?
You need a Stata code pattern for an empirical accounting method used in published JAR papers.
What you get
Cited Stata code patterns for the requested method, adapted to your variable names.
- Stata code adapted to your variable names
By the numbers
- 126 peer-reviewed JAR replication files
- 54 panel fixed-effects files
- 22 difference-in-differences files
Files
STATA Accounting Research
A Claude Code skill providing STATA syntax patterns from 126 peer-reviewed JAR replication files (2017-2025).
What is a Claude Skill?
A skill extends Claude Code with specialized knowledge and workflows. When installed, this skill enables natural language queries for STATA syntax patterns used in empirical accounting research.
Installation
1. Download this repo as a zip file 2. In Claude, go to Settings > Capabilities > Skills > Add > Upload
Alternatively, clone this repository to ~/.claude/skills
What This Skill Does
| Provides | Does Not Provide |
|---|---|
| STATA syntax from published papers | Research design advice |
| Multiple implementations of the same method | Identification strategy recommendations |
| Code adapted to your variable names | Methodological trade-off analysis |
| Source citations for patterns | Data or sample construction |
Example
Query:
How do I implement entropy balancing? My treatment variable is 'cyber_breach' and I want to balance on 'size', 'roa', and 'leverage'
Response:
* Step 1: Generate entropy balancing weights
ebalance cyber_breach size roa leverage, target(1) generate(ebw)
* Step 2: Use weights in regression
reghdfe depvar cyber_breach controls [aw=ebw], absorb(firm year) cluster(firm)| Option | Meaning |
|---|---|
target(1) | Balance means only (most common) |
target(2) | Balance means + variances |
target(3) | Balance means + variances + skewness |
Alternative from Nessa et al. (2025), JAR 63(2) — balance by year when treatment timing varies:
forvalues y = 2015/2022 {
qui ebalance cyber_breach size roa leverage if year==`y', generate(ew`y') tar(1)
}Contents
This skill includes only STATA .do files. Other file types (SAS, R, Python, data files) from the original replication packages are not included.
references/
├── REFERENCES.md # Index with methods and identification strategies
└── JAR_*.do # 126 STATA replication files (Volumes 55-63)Method Coverage
| Method | Files |
|---|---|
| Panel fixed effects (reghdfe, xtreg, areg) | 54 |
| Difference-in-differences | 22 |
| Event studies (CAR/BHAR) | 19 |
| Propensity score matching | 10 |
| Entropy balancing | 5 |
| Survival/duration analysis | 4 |
| Instrumental variables | 3 |
| Regression discontinuity | 2 |
File Naming Convention
- Volumes 55-61:
JAR_{volume}_{shortcode}.do - Volumes 62-63:
JAR_{volume}_{issue}_{shortcode}_{authors}.do
Original Source
The .do files are sourced from the Journal of Accounting Research Online Supplements: https://www.chicagobooth.edu/research/chookaszian/journal-of-accounting-research/online-supplements-and-datasheets
Methodological References
For research design guidance, consult:
- Breuer & deHaan (2024) on fixed effects interpretation
- Angrist & Pischke (2009) on causal inference
*********************************************************************************************************************************************************
*
* The Effect of Regulatory Harmonization on Cross-Border Labor Migration: Evidence from the Accounting Profession
*
* Matthew J. Bloomfield, Ulf Bruggemann, Hans B. Christensen and Christian Leuz
*
* This do-file shows the code for the main empirical analysis presented in Table 3 of the paper.
* The analysis is based on the EU Labour Force Survey (LFS) core data (version: December 2012).
* We use the annual files for 29 European countries for years 2002 to 2004 and 2008 to 2010, respectively.
*
*********************************************************************************************************************************************************
*********************************************************************************************************************************************************
* I. Data preparation
*********************************************************************************************************************************************************
**************************************************************************************************************
* Step 1: Read and clean key LFS items
**************************************************************************************************************
clear
gen country = ""
save BBCL_Data_raw, replace
local varlist at be bg ch cy cz de dk ee es fi fr gr hu ie is it lt lu lv nl no pl pt ro se si sk uk
qui foreach country of local varlist {
qui foreach year in 2002 2003 2004 2008 2009 2010 {
use EU_LFS_yr_`country'`year', clear
* Clean job code item
tostring isco3d, replace
replace isco3d = "" if isco3d == "."
replace isco3d = "0" if isco3d == "0 0" | isco3d == "010"
destring isco3d, replace
* Clean items related to mobility
tostring countryb national yearesid countr1y, replace
gen countryb_own = (countryb == "OWN COUNTRY" | countryb == "0" | substr(countryb,1,3) == "000")
gen countryb_na = (countryb == "NO ANSWER")
gen national_own = (national == "OWN COUNTRY" | national == "0" | substr(national,1,3) == "000")
gen national_na = (national == "NO ANSWER")
gen source_eu15 = ((countryb == "001-EU15" | countryb == "111") & (national == "001-EU15" | national == "111"))
replace yearesid = "NA" if yearesid == "." | yearesid == ""
replace yearesid = substr(yearesid,2,length(yearesid)-1) if substr(yearesid,1,1) == "0" & yearesid != "0"
gen countr1y_own = (countr1y == country)
gen countr1y_na = (countr1y == "NO ANSWER" | countr1y == "." | countr1y == "" | countr1y == "99" | real(countr1y) <= 14)
* Focus on key LFS items
keep country year isco3d countryb_* national_* source_eu15 yearesid countr1y_* sex age marstat hhlink qhhnum hatlevel hatyear sizefirm startime coeffy
order country year isco3d countryb_* national_* source_eu15 yearesid countr1y_* sex age marstat hhlink qhhnum hatlevel hatyear sizefirm startime coeffy
append using BBCL_Data_raw
compress
save BBCL_Data_raw, replace
}
}
**************************************************************************************************************
* Step 2: Impose sample restrictions and compute key variables
**************************************************************************************************************
use BBCL_Data_raw, clear
* Compute mobility metrics
gen mob_natbirth = (countryb_own == 0 & yearesid != "0" & national_own == 0)
replace mob_natbirth = . if (countryb_na == 1 & yearesid == "NA") | national_na == 1
gen mob_natbirth_eu15 = mob_natbirth
replace mob_natbirth_eu15 = 0 if source_eu15 == 0 & mob_natbirth == 1
gen startime_adj = startime + 6
gen startime_yrs = floor(startime_adj/12)
gen startyear = year - startime_yrs
gen recent = (startyear >= 1999 & year < 2005) | (startyear >= 2005 & year > 2005)
replace recent = . if startyear == .
gen mob_natbirth_chg = (mob_natbirth == 1 & recent == 1)
replace mob_natbirth_chg = . if startyear == . | mob_natbirth==.
gen mob_yearesid = 0
replace mob_yearesid = 1 if ((year == 2004 | year == 2010) & (yearesid == "1" | yearesid == "2" | yearesid == "3" | yearesid == "4" | yearesid == "5"))
replace mob_yearesid = 1 if ((year == 2003 | year == 2009) & (yearesid == "1" | yearesid == "2" | yearesid == "3" | yearesid == "4"))
replace mob_yearesid = 1 if ((year == 2002 | year == 2008) & (yearesid == "1" | yearesid == "2" | yearesid == "3"))
replace mob_yearesid = . if yearesid == "NA" | (year >= 2005 & year <= 2007)
gen mob_countr1y = (countr1y_own != 1)
replace mob_countr1y = . if countr1y_na == 1
* Compute controls
*** Female yes/no
gen female = (sex == 2)
*** Has kids yes/no
gen help = (hhlink == 3) if age < 15
bysort country year qhhnum: egen hhlink3 = sum(help)
bysort country year: egen hhlink3_max = max(hhlink3)
replace hhlink3 = . if hhlink3_max == 0
rename hhlink3 hhkids
gen haskids = (hhkids >= 1)
replace haskids = -1 if hhkids == .
replace haskids = -1 if country == "IE"
/* haskids set to missing for Ireland (see footnote 15 in the paper) */
*** Single yes/no
gen single = (marstat == 1)
replace single = . if marstat ==.
*** Higher education yes/no
gen education_pre = floor(hatlevel/10)
gen education = (education_pre == 5 | education_pre == 6)
replace education = . if education_pre < 3 | education_pre == .
* Sample restrictions
*** Age restriction
keep if age >= 20 & age <= 59
*** Drop countries that do not provide ISCO3D information at three-digit level (see footnote 12 in the paper)
drop if country == "BG" | country == "PL" | country == "SI"
*** Drop professions subject to confounding regulatory treatment
drop if isco3d == 214 | isco3d == 222 | isco3d == 223
* Define samples
gen sample_acc = (isco3d == 241)
gen sample_law = (isco3d == 242)
gen sample_pro = (isco3d >= 200 & isco3d < 300 & isco3d != 241)
gen sample_biz = (isco3d == 121 | isco3d == 122 | isco3d == 123 | isco3d == 131 | isco3d == 341 | isco3d == 342)
keep if sample_acc == 1 | sample_law == 1 | sample_pro == 1 | sample_biz == 1
keep country year sample_* mob_* recent female age haskids single education sizefirm coeffy
compress
save BBCL_Data_clean, replace
*********************************************************************************************************************************************************
* II. Data analysis
*********************************************************************************************************************************************************
log using "BBCL_LM_Code.log", replace
**************************************************************************************************************
* Table 3, Panel A and B: Baseline regressions without/with domestic job mobility control
**************************************************************************************************************
use BBCL_Data_clean, clear
* Prepare regressions
*** Determine regression samples
gen sample_1 = (sample_acc == 1 | sample_law == 1)
gen sample_2 = (sample_acc == 1 | sample_pro == 1)
gen sample_3 = (sample_acc == 1 | sample_biz == 1)
*** Require mob_natbirth and mob_natbirth_chg to be non-missing
keep if mob_natbirth != . & mob_natbirth_chg != .
*** Compute test variables
gen treatment = sample_acc
gen post = (year > 2005)
gen treatment_post = treatment*post
*** Compute domestic job mobility control
qui forvalues i = 1/3 {
gen dom_obs_unwght = 1 if mob_natbirth == 0 & sample_`i' == 1
gen dom_recent_unwght = 1 if mob_natbirth == 0 & recent == 1 & sample_`i' == 1
gen dom_obs_wght = coeffy if mob_natbirth == 0 & sample_`i' == 1
gen dom_recent_wght = coeffy if mob_natbirth == 0 & recent == 1 & sample_`i' == 1
bysort country year treatment: egen help1 = sum(dom_obs_unwght)
bysort country year treatment: egen help2 = sum(dom_recent_unwght)
gen dom_mob_unwght_`i' = (help2/help1)*100
bysort country year treatment: egen help3 = sum(dom_obs_wght)
bysort country year treatment: egen help4 = sum(dom_recent_wght)
gen dom_mob_wght_`i' = (help4/help3)*100
drop dom_obs* dom_recent_* help*
}
*** Prepare fixed effects
egen bin = group(female age single haskids education)
egen country_job = group(country treatment)
egen country_year = group(country year)
* Regressions without domestic job mobility control (Panel A)
forvalues i = 1/3 {
preserve
keep if sample_`i' == 1
keep if coeffy != . & coeffy > 0
reghdfe mob_natbirth treatment_post [aweight = coeffy], absorb(bin country_job country_year) cluster(country_job) keepsingleton
restore
}
forvalues i = 1/3 {
preserve
keep if sample_`i' == 1
reghdfe mob_natbirth treatment_post, absorb(bin country_job country_year) cluster(country_job) keepsingleton
restore
}
forvalues i = 1/3 {
preserve
keep if sample_`i' == 1
keep if coeffy != . & coeffy > 0
reghdfe mob_natbirth_chg treatment_post [aweight = coeffy], absorb(bin country_job country_year) cluster(country_job) keepsingleton
restore
}
forvalues i = 1/3 {
preserve
keep if sample_`i' == 1
reghdfe mob_natbirth_chg treatment_post, absorb(bin country_job country_year) cluster(country_job) keepsingleton
restore
}
* Regressions with domestic job mobility control (Panel B)
forvalues i = 1/3 {
preserve
keep if sample_`i' == 1
keep if coeffy != . & coeffy > 0
rename dom_mob_wght_`i' dom_mob_wght
reghdfe mob_natbirth treatment_post dom_mob_wght [aweight = coeffy], absorb(bin country_job country_year) cluster(country_job) keepsingleton
restore
}
forvalues i = 1/3 {
preserve
keep if sample_`i' == 1
rename dom_mob_unwght_`i' dom_mob_unwght
reghdfe mob_natbirth treatment_post dom_mob_unwght, absorb(bin country_job country_year) cluster(country_job) keepsingleton
restore
}
forvalues i = 1/3 {
preserve
keep if sample_`i' == 1
keep if coeffy != . & coeffy > 0
rename dom_mob_wght_`i' dom_mob_wght
reghdfe mob_natbirth_chg treatment_post dom_mob_wght [aweight = coeffy], absorb(bin country_job country_year) cluster(country_job) keepsingleton
restore
}
forvalues i = 1/3 {
preserve
keep if sample_`i' == 1
rename dom_mob_unwght_`i' dom_mob_unwght
reghdfe mob_natbirth_chg treatment_post dom_mob_unwght, absorb(bin country_job country_year) cluster(country_job) keepsingleton
restore
}
**************************************************************************************************************
* Table 3, Panel C: Double matched diff-in-diff analysis
**************************************************************************************************************
* Double matching
local matchvars single haskids age education female
local controlgroups sample_law sample_pro sample_biz
local mobilitymeasures natbirth natbirth_chg
local onlyrecentyesno 0 1
local coeffyweightsyesno 0 1
qui foreach control in `controlgroups' {
foreach measure in `mobilitymeasures' {
foreach onlyrecent in `onlyrecentyesno' {
foreach coeffyweight in `coeffyweightsyesno' {
use BBCL_Data_clean, clear
*** Require mob_natbirth and mob_natbirth_chg to be non-missing
keep if mob_natbirth != . & mob_natbirth_chg != .
if `onlyrecent'==1 {
keep if recent == 1
}
if `coeffyweight'==1 {
drop if coeffy == 0 | coeffy == .
}
foreach matchvar in `matchvars' {
drop if `matchvar' == .
}
gen mobility = mob_`measure'
keep if mobility != .
gen treatment = sample_acc
gen post = (year > 2005)
gen control = `control'
keep if treatment == 1 | control == 1
*** 2002 matched to 2008
*** 2003 matched to 2009
*** 2004 matched to 2010
gen matchyear = year-6*(post==1)
*** This is for any individual isco3d control group
gen iscontrolpre = control*(1-post)
gen istreatedpre = treatment*(1-post)
gen iscontrolpost = control*post
gen istreatedpost = treatment*post
*** Identify number of obs in each cell
sort country matchyear `matchvars'
by country matchyear `matchvars': egen numcontrolpre = sum(iscontrolpre)
by country matchyear `matchvars': egen numtreatedpre = sum(istreatedpre)
by country matchyear `matchvars': egen numcontrolpost = sum(iscontrolpost)
by country matchyear `matchvars': egen numtreatedpost = sum(istreatedpost)
gen matched = 0
gen matchweight = 0
*** Identify observations in "common-support" (at least 1 obs in pre-treat, post-treat, pre-control and post-control)
replace matched = 1 if numcontrolpre > 0 & numtreatedpre > 0 & numtreatedpost > 0 & numcontrolpost > 0
*** Matched accountants in pre-period get a weight of 1. Everyone else gets the required "balancing" weight.
replace matchweight = 1 if treatment == 1 & matched == 1 & post == 0
replace matchweight = numtreatedpre/numcontrolpre if control == 1 & matched == 1 & post == 0
replace matchweight = numtreatedpre/numcontrolpost if control == 1 & matched == 1 & post == 1
replace matchweight = numtreatedpre/numtreatedpost if treatment == 1 & matched == 1 & post == 1
*** Check your work: only difference should be number of observations
*** Weights of all should be equal to number of observations for pre-period accountants
noisily summarize `matchvars' [aweight=matchweight] if treatment == 1 & post == 0
noisily summarize `matchvars' [aweight=matchweight] if treatment == 1 & post == 1
noisily summarize `matchvars' [aweight=matchweight] if control == 1 & post == 0
noisily summarize `matchvars' [aweight=matchweight] if control == 1 & post == 1
*** Keep only matched observations
keep if matched == 1
noisily save "doublematchedsample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", replace
}
}
}
}
*** Doublematched country-matchyear-matchvariable-level analysis (NATBIRTH)
qui foreach control in `controlgroups' {
foreach measure in `mobilitymeasures' {
foreach onlyrecent in `onlyrecentyesno' {
foreach coeffyweight in `coeffyweightsyesno' {
*** Aggregate coeffy-weights by match bin
use "doublematchedsample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
statsby meancoeffy=r(mean) sample=r(N), by(`matchvars' country matchyear) nodots clear: summarize coeffy [aweight=matchweight]
gen coeffyweight=meancoeffy*sample
keep `matchvars' country matchyear coeffyweight
save "coeffyweights.dta", replace
use "doublematchedsample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
*** Aggregate mobility by match bin
statsby meanmobility = r(mean) sample=r(N), by(`matchvars' country matchyear treatment post) nodots clear: summarize mobility
sort `matchvars' country matchyear treatment
*** Calculate sample of smallest bin without each double-matched quadruplet
*** This will be the statistical weighting on the quadruplets diff-in-diff
by `matchvars' country matchyear: egen minsample = min(sample)
by `matchvars' country matchyear: egen bincount = count(sample)
drop if bincount != 4
drop if minsample == 0
merge m:1 `matchvars' country matchyear using "coeffyweights.dta", nogenerate
*** Construct binning variables for clustering and FE's----we use 'country_job' for clusters and 'bin' for FE's
egen bin = group(country matchyear post `matchvars')
egen country_job = group(country treatment)
noisily save "readyforregssample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", replace
}
}
}
}
* Difference-in-differences analysis: full sample, NATBIRTH, LFS weighted (no)
local control sample_pro
local measure natbirth
local onlyrecent 0
local coeffyweight 0
use "doublematchedsample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
tabulate treatment
use "readyforregssample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
gen treatment_post = treatment*post
*** Convert mobility to percent
replace meanmobility = 100*meanmobility
rename meanmobility meanmobility`mob'
*** Main effect of post is subsumed by FEs
areg meanmobility treatment_post treatment [aweight=minsample], absorb(bin) cluster(country_job)
sort treatment post
by treatment post: summarize meanmobility [aweight=minsample]
* Difference-in-differences analysis: full sample, NATBIRTH, LFS weighted (yes)
local control sample_pro
local measure natbirth
local onlyrecent 0
local coeffyweight 1
use "doublematchedsample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
tabulate treatment
use "readyforregssample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
gen treatment_post = treatment*post
*** Convert mobility to percent
replace meanmobility=100*meanmobility
rename meanmobility meanmobility`mob'
*** Main effect of post is subsumed by FEs
areg meanmobility treatment_post treatment [aweight=minsample*coeffyweight], absorb(bin) cluster(country_job)
sort treatment post
by treatment post: summarize meanmobility [aweight=minsample*coeffyweight]
* Difference-in-differences analysis: full sample, NATBIRTH_CHG, LFS weighted (no)
local control sample_pro
local measure natbirth_chg
local onlyrecent 0
local coeffyweight 0
use "doublematchedsample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
tabulate treatment
use "readyforregssample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
gen treatment_post = treatment*post
*** Convert mobility to percent
replace meanmobility=100*meanmobility
rename meanmobility meanmobility`mob'
*** Main effect of post is subsumed by FEs
areg meanmobility treatment_post treatment [aweight=minsample], absorb(bin) cluster(country_job)
sort treatment post
by treatment post: summarize meanmobility [aweight=minsample]
* Difference-in-differences analysis: full sample, NATBIRTH_CHG, LFS weighted (yes)
local control sample_pro
local measure natbirth_chg
local onlyrecent 0
local coeffyweight 1
use "doublematchedsample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
tabulate treatment
use "readyforregssample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
gen treatment_post = treatment*post
*** Convert mobility to percent
replace meanmobility=100*meanmobility
rename meanmobility meanmobility`mob'
*** Main effect of post is subsumed by FEs
areg meanmobility treatment_post treatment [aweight=minsample*coeffyweight], absorb(bin) cluster(country_job)
sort treatment post
by treatment post: summarize meanmobility [aweight=minsample*coeffyweight]
* Difference-in-differences analysis: only recent job changers, NATBIRTH, LFS weighted (no)
local control sample_pro
local measure natbirth
local onlyrecent 1
local coeffyweight 0
use "doublematchedsample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
tabulate treatment
use "readyforregssample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
gen treatment_post = treatment*post
*** Convert mobility to percent
replace meanmobility=100*meanmobility
rename meanmobility meanmobility`mob'
*** Main effect of post is subsumed by FEs
areg meanmobility treatment_post treatment [aweight=minsample], absorb(bin) cluster(country_job)
sort treatment post
by treatment post: summarize meanmobility [aweight=minsample]
* Difference-in-differences analysis: only recent job changers, NATBIRTH, LFS weighted (yes)
local control sample_pro
local measure natbirth
local onlyrecent 1
local coeffyweight 1
use "doublematchedsample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
tabulate treatment
use "readyforregssample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
gen treatment_post = treatment*post
*** Convert mobility to percent
replace meanmobility = 100*meanmobility
rename meanmobility meanmobility`mob'
*** Main effect of post is subsumed by FEs
areg meanmobility treatment_post treatment [aweight=minsample*coeffyweight], absorb(bin) cluster(country_job)
sort treatment post
by treatment post: summarize meanmobility [aweight=minsample*coeffyweight]
log close
*********************************************************************************************************************************************************
*
* The Effect of Regulatory Harmonization on Cross-Border Labor Migration: Evidence from the Accounting Profession
*
* Matthew J. Bloomfield, Ulf Bruggemann, Hans B. Christensen and Christian Leuz
*
* This do-file shows the code for the main empirical analysis presented in Table 3 of the paper.
* The analysis is based on the EU Labour Force Survey (LFS) core data (version: December 2012).
* We use the annual files for 29 European countries for years 2002 to 2004 and 2008 to 2010, respectively.
*
*********************************************************************************************************************************************************
*********************************************************************************************************************************************************
* I. Data preparation
*********************************************************************************************************************************************************
**************************************************************************************************************
* Step 1: Read and clean key LFS items
**************************************************************************************************************
clear
gen country = ""
save BBCL_Data_raw, replace
local varlist at be bg ch cy cz de dk ee es fi fr gr hu ie is it lt lu lv nl no pl pt ro se si sk uk
qui foreach country of local varlist {
qui foreach year in 2002 2003 2004 2008 2009 2010 {
use EU_LFS_yr_`country'`year', clear
* Clean job code item
tostring isco3d, replace
replace isco3d = "" if isco3d == "."
replace isco3d = "0" if isco3d == "0 0" | isco3d == "010"
destring isco3d, replace
* Clean items related to mobility
tostring countryb national yearesid countr1y, replace
gen countryb_own = (countryb == "OWN COUNTRY" | countryb == "0" | substr(countryb,1,3) == "000")
gen countryb_na = (countryb == "NO ANSWER")
gen national_own = (national == "OWN COUNTRY" | national == "0" | substr(national,1,3) == "000")
gen national_na = (national == "NO ANSWER")
gen source_eu15 = ((countryb == "001-EU15" | countryb == "111") & (national == "001-EU15" | national == "111"))
replace yearesid = "NA" if yearesid == "." | yearesid == ""
replace yearesid = substr(yearesid,2,length(yearesid)-1) if substr(yearesid,1,1) == "0" & yearesid != "0"
gen countr1y_own = (countr1y == country)
gen countr1y_na = (countr1y == "NO ANSWER" | countr1y == "." | countr1y == "" | countr1y == "99" | real(countr1y) <= 14)
* Focus on key LFS items
keep country year isco3d countryb_* national_* source_eu15 yearesid countr1y_* sex age marstat hhlink qhhnum hatlevel hatyear sizefirm startime coeffy
order country year isco3d countryb_* national_* source_eu15 yearesid countr1y_* sex age marstat hhlink qhhnum hatlevel hatyear sizefirm startime coeffy
append using BBCL_Data_raw
compress
save BBCL_Data_raw, replace
}
}
**************************************************************************************************************
* Step 2: Impose sample restrictions and compute key variables
**************************************************************************************************************
use BBCL_Data_raw, clear
* Compute mobility metrics
gen mob_natbirth = (countryb_own == 0 & yearesid != "0" & national_own == 0)
replace mob_natbirth = . if (countryb_na == 1 & yearesid == "NA") | national_na == 1
gen mob_natbirth_eu15 = mob_natbirth
replace mob_natbirth_eu15 = 0 if source_eu15 == 0 & mob_natbirth == 1
gen startime_adj = startime + 6
gen startime_yrs = floor(startime_adj/12)
gen startyear = year - startime_yrs
gen recent = (startyear >= 1999 & year < 2005) | (startyear >= 2005 & year > 2005)
replace recent = . if startyear == .
gen mob_natbirth_chg = (mob_natbirth == 1 & recent == 1)
replace mob_natbirth_chg = . if startyear == . | mob_natbirth==.
gen mob_yearesid = 0
replace mob_yearesid = 1 if ((year == 2004 | year == 2010) & (yearesid == "1" | yearesid == "2" | yearesid == "3" | yearesid == "4" | yearesid == "5"))
replace mob_yearesid = 1 if ((year == 2003 | year == 2009) & (yearesid == "1" | yearesid == "2" | yearesid == "3" | yearesid == "4"))
replace mob_yearesid = 1 if ((year == 2002 | year == 2008) & (yearesid == "1" | yearesid == "2" | yearesid == "3"))
replace mob_yearesid = . if yearesid == "NA" | (year >= 2005 & year <= 2007)
gen mob_countr1y = (countr1y_own != 1)
replace mob_countr1y = . if countr1y_na == 1
* Compute controls
*** Female yes/no
gen female = (sex == 2)
*** Has kids yes/no
gen help = (hhlink == 3) if age < 15
bysort country year qhhnum: egen hhlink3 = sum(help)
bysort country year: egen hhlink3_max = max(hhlink3)
replace hhlink3 = . if hhlink3_max == 0
rename hhlink3 hhkids
gen haskids = (hhkids >= 1)
replace haskids = -1 if hhkids == .
replace haskids = -1 if country == "IE"
/* haskids set to missing for Ireland (see footnote 15 in the paper) */
*** Single yes/no
gen single = (marstat == 1)
replace single = . if marstat ==.
*** Higher education yes/no
gen education_pre = floor(hatlevel/10)
gen education = (education_pre == 5 | education_pre == 6)
replace education = . if education_pre < 3 | education_pre == .
* Sample restrictions
*** Age restriction
keep if age >= 20 & age <= 59
*** Drop countries that do not provide ISCO3D information at three-digit level (see footnote 12 in the paper)
drop if country == "BG" | country == "PL" | country == "SI"
*** Drop professions subject to confounding regulatory treatment
drop if isco3d == 214 | isco3d == 222 | isco3d == 223
* Define samples
gen sample_acc = (isco3d == 241)
gen sample_law = (isco3d == 242)
gen sample_pro = (isco3d >= 200 & isco3d < 300 & isco3d != 241)
gen sample_biz = (isco3d == 121 | isco3d == 122 | isco3d == 123 | isco3d == 131 | isco3d == 341 | isco3d == 342)
keep if sample_acc == 1 | sample_law == 1 | sample_pro == 1 | sample_biz == 1
keep country year sample_* mob_* recent female age haskids single education sizefirm coeffy
compress
save BBCL_Data_clean, replace
*********************************************************************************************************************************************************
* II. Data analysis
*********************************************************************************************************************************************************
log using "BBCL_LM_Code.log", replace
**************************************************************************************************************
* Table 3, Panel A and B: Baseline regressions without/with domestic job mobility control
**************************************************************************************************************
use BBCL_Data_clean, clear
* Prepare regressions
*** Determine regression samples
gen sample_1 = (sample_acc == 1 | sample_law == 1)
gen sample_2 = (sample_acc == 1 | sample_pro == 1)
gen sample_3 = (sample_acc == 1 | sample_biz == 1)
*** Require mob_natbirth and mob_natbirth_chg to be non-missing
keep if mob_natbirth != . & mob_natbirth_chg != .
*** Compute test variables
gen treatment = sample_acc
gen post = (year > 2005)
gen treatment_post = treatment*post
*** Compute domestic job mobility control
qui forvalues i = 1/3 {
gen dom_obs_unwght = 1 if mob_natbirth == 0 & sample_`i' == 1
gen dom_recent_unwght = 1 if mob_natbirth == 0 & recent == 1 & sample_`i' == 1
gen dom_obs_wght = coeffy if mob_natbirth == 0 & sample_`i' == 1
gen dom_recent_wght = coeffy if mob_natbirth == 0 & recent == 1 & sample_`i' == 1
bysort country year treatment: egen help1 = sum(dom_obs_unwght)
bysort country year treatment: egen help2 = sum(dom_recent_unwght)
gen dom_mob_unwght_`i' = (help2/help1)*100
bysort country year treatment: egen help3 = sum(dom_obs_wght)
bysort country year treatment: egen help4 = sum(dom_recent_wght)
gen dom_mob_wght_`i' = (help4/help3)*100
drop dom_obs* dom_recent_* help*
}
*** Prepare fixed effects
egen bin = group(female age single haskids education)
egen country_job = group(country treatment)
egen country_year = group(country year)
* Regressions without domestic job mobility control (Panel A)
forvalues i = 1/3 {
preserve
keep if sample_`i' == 1
keep if coeffy != . & coeffy > 0
reghdfe mob_natbirth treatment_post [aweight = coeffy], absorb(bin country_job country_year) cluster(country_job) keepsingleton
restore
}
forvalues i = 1/3 {
preserve
keep if sample_`i' == 1
reghdfe mob_natbirth treatment_post, absorb(bin country_job country_year) cluster(country_job) keepsingleton
restore
}
forvalues i = 1/3 {
preserve
keep if sample_`i' == 1
keep if coeffy != . & coeffy > 0
reghdfe mob_natbirth_chg treatment_post [aweight = coeffy], absorb(bin country_job country_year) cluster(country_job) keepsingleton
restore
}
forvalues i = 1/3 {
preserve
keep if sample_`i' == 1
reghdfe mob_natbirth_chg treatment_post, absorb(bin country_job country_year) cluster(country_job) keepsingleton
restore
}
* Regressions with domestic job mobility control (Panel B)
forvalues i = 1/3 {
preserve
keep if sample_`i' == 1
keep if coeffy != . & coeffy > 0
rename dom_mob_wght_`i' dom_mob_wght
reghdfe mob_natbirth treatment_post dom_mob_wght [aweight = coeffy], absorb(bin country_job country_year) cluster(country_job) keepsingleton
restore
}
forvalues i = 1/3 {
preserve
keep if sample_`i' == 1
rename dom_mob_unwght_`i' dom_mob_unwght
reghdfe mob_natbirth treatment_post dom_mob_unwght, absorb(bin country_job country_year) cluster(country_job) keepsingleton
restore
}
forvalues i = 1/3 {
preserve
keep if sample_`i' == 1
keep if coeffy != . & coeffy > 0
rename dom_mob_wght_`i' dom_mob_wght
reghdfe mob_natbirth_chg treatment_post dom_mob_wght [aweight = coeffy], absorb(bin country_job country_year) cluster(country_job) keepsingleton
restore
}
forvalues i = 1/3 {
preserve
keep if sample_`i' == 1
rename dom_mob_unwght_`i' dom_mob_unwght
reghdfe mob_natbirth_chg treatment_post dom_mob_unwght, absorb(bin country_job country_year) cluster(country_job) keepsingleton
restore
}
**************************************************************************************************************
* Table 3, Panel C: Double matched diff-in-diff analysis
**************************************************************************************************************
* Double matching
local matchvars single haskids age education female
local controlgroups sample_law sample_pro sample_biz
local mobilitymeasures natbirth natbirth_chg
local onlyrecentyesno 0 1
local coeffyweightsyesno 0 1
qui foreach control in `controlgroups' {
foreach measure in `mobilitymeasures' {
foreach onlyrecent in `onlyrecentyesno' {
foreach coeffyweight in `coeffyweightsyesno' {
use BBCL_Data_clean, clear
*** Require mob_natbirth and mob_natbirth_chg to be non-missing
keep if mob_natbirth != . & mob_natbirth_chg != .
if `onlyrecent'==1 {
keep if recent == 1
}
if `coeffyweight'==1 {
drop if coeffy == 0 | coeffy == .
}
foreach matchvar in `matchvars' {
drop if `matchvar' == .
}
gen mobility = mob_`measure'
keep if mobility != .
gen treatment = sample_acc
gen post = (year > 2005)
gen control = `control'
keep if treatment == 1 | control == 1
*** 2002 matched to 2008
*** 2003 matched to 2009
*** 2004 matched to 2010
gen matchyear = year-6*(post==1)
*** This is for any individual isco3d control group
gen iscontrolpre = control*(1-post)
gen istreatedpre = treatment*(1-post)
gen iscontrolpost = control*post
gen istreatedpost = treatment*post
*** Identify number of obs in each cell
sort country matchyear `matchvars'
by country matchyear `matchvars': egen numcontrolpre = sum(iscontrolpre)
by country matchyear `matchvars': egen numtreatedpre = sum(istreatedpre)
by country matchyear `matchvars': egen numcontrolpost = sum(iscontrolpost)
by country matchyear `matchvars': egen numtreatedpost = sum(istreatedpost)
gen matched = 0
gen matchweight = 0
*** Identify observations in "common-support" (at least 1 obs in pre-treat, post-treat, pre-control and post-control)
replace matched = 1 if numcontrolpre > 0 & numtreatedpre > 0 & numtreatedpost > 0 & numcontrolpost > 0
*** Matched accountants in pre-period get a weight of 1. Everyone else gets the required "balancing" weight.
replace matchweight = 1 if treatment == 1 & matched == 1 & post == 0
replace matchweight = numtreatedpre/numcontrolpre if control == 1 & matched == 1 & post == 0
replace matchweight = numtreatedpre/numcontrolpost if control == 1 & matched == 1 & post == 1
replace matchweight = numtreatedpre/numtreatedpost if treatment == 1 & matched == 1 & post == 1
*** Check your work: only difference should be number of observations
*** Weights of all should be equal to number of observations for pre-period accountants
noisily summarize `matchvars' [aweight=matchweight] if treatment == 1 & post == 0
noisily summarize `matchvars' [aweight=matchweight] if treatment == 1 & post == 1
noisily summarize `matchvars' [aweight=matchweight] if control == 1 & post == 0
noisily summarize `matchvars' [aweight=matchweight] if control == 1 & post == 1
*** Keep only matched observations
keep if matched == 1
noisily save "doublematchedsample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", replace
}
}
}
}
*** Doublematched country-matchyear-matchvariable-level analysis (NATBIRTH)
qui foreach control in `controlgroups' {
foreach measure in `mobilitymeasures' {
foreach onlyrecent in `onlyrecentyesno' {
foreach coeffyweight in `coeffyweightsyesno' {
*** Aggregate coeffy-weights by match bin
use "doublematchedsample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
statsby meancoeffy=r(mean) sample=r(N), by(`matchvars' country matchyear) nodots clear: summarize coeffy [aweight=matchweight]
gen coeffyweight=meancoeffy*sample
keep `matchvars' country matchyear coeffyweight
save "coeffyweights.dta", replace
use "doublematchedsample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
*** Aggregate mobility by match bin
statsby meanmobility = r(mean) sample=r(N), by(`matchvars' country matchyear treatment post) nodots clear: summarize mobility
sort `matchvars' country matchyear treatment
*** Calculate sample of smallest bin without each double-matched quadruplet
*** This will be the statistical weighting on the quadruplets diff-in-diff
by `matchvars' country matchyear: egen minsample = min(sample)
by `matchvars' country matchyear: egen bincount = count(sample)
drop if bincount != 4
drop if minsample == 0
merge m:1 `matchvars' country matchyear using "coeffyweights.dta", nogenerate
*** Construct binning variables for clustering and FE's----we use 'country_job' for clusters and 'bin' for FE's
egen bin = group(country matchyear post `matchvars')
egen country_job = group(country treatment)
noisily save "readyforregssample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", replace
}
}
}
}
* Difference-in-differences analysis: full sample, NATBIRTH, LFS weighted (no)
local control sample_pro
local measure natbirth
local onlyrecent 0
local coeffyweight 0
use "doublematchedsample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
tabulate treatment
use "readyforregssample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
gen treatment_post = treatment*post
*** Convert mobility to percent
replace meanmobility = 100*meanmobility
rename meanmobility meanmobility`mob'
*** Main effect of post is subsumed by FEs
areg meanmobility treatment_post treatment [aweight=minsample], absorb(bin) cluster(country_job)
sort treatment post
by treatment post: summarize meanmobility [aweight=minsample]
* Difference-in-differences analysis: full sample, NATBIRTH, LFS weighted (yes)
local control sample_pro
local measure natbirth
local onlyrecent 0
local coeffyweight 1
use "doublematchedsample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
tabulate treatment
use "readyforregssample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
gen treatment_post = treatment*post
*** Convert mobility to percent
replace meanmobility=100*meanmobility
rename meanmobility meanmobility`mob'
*** Main effect of post is subsumed by FEs
areg meanmobility treatment_post treatment [aweight=minsample*coeffyweight], absorb(bin) cluster(country_job)
sort treatment post
by treatment post: summarize meanmobility [aweight=minsample*coeffyweight]
* Difference-in-differences analysis: full sample, NATBIRTH_CHG, LFS weighted (no)
local control sample_pro
local measure natbirth_chg
local onlyrecent 0
local coeffyweight 0
use "doublematchedsample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
tabulate treatment
use "readyforregssample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
gen treatment_post = treatment*post
*** Convert mobility to percent
replace meanmobility=100*meanmobility
rename meanmobility meanmobility`mob'
*** Main effect of post is subsumed by FEs
areg meanmobility treatment_post treatment [aweight=minsample], absorb(bin) cluster(country_job)
sort treatment post
by treatment post: summarize meanmobility [aweight=minsample]
* Difference-in-differences analysis: full sample, NATBIRTH_CHG, LFS weighted (yes)
local control sample_pro
local measure natbirth_chg
local onlyrecent 0
local coeffyweight 1
use "doublematchedsample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
tabulate treatment
use "readyforregssample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
gen treatment_post = treatment*post
*** Convert mobility to percent
replace meanmobility=100*meanmobility
rename meanmobility meanmobility`mob'
*** Main effect of post is subsumed by FEs
areg meanmobility treatment_post treatment [aweight=minsample*coeffyweight], absorb(bin) cluster(country_job)
sort treatment post
by treatment post: summarize meanmobility [aweight=minsample*coeffyweight]
* Difference-in-differences analysis: only recent job changers, NATBIRTH, LFS weighted (no)
local control sample_pro
local measure natbirth
local onlyrecent 1
local coeffyweight 0
use "doublematchedsample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
tabulate treatment
use "readyforregssample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
gen treatment_post = treatment*post
*** Convert mobility to percent
replace meanmobility=100*meanmobility
rename meanmobility meanmobility`mob'
*** Main effect of post is subsumed by FEs
areg meanmobility treatment_post treatment [aweight=minsample], absorb(bin) cluster(country_job)
sort treatment post
by treatment post: summarize meanmobility [aweight=minsample]
* Difference-in-differences analysis: only recent job changers, NATBIRTH, LFS weighted (yes)
local control sample_pro
local measure natbirth
local onlyrecent 1
local coeffyweight 1
use "doublematchedsample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
tabulate treatment
use "readyforregssample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
gen treatment_post = treatment*post
*** Convert mobility to percent
replace meanmobility = 100*meanmobility
rename meanmobility meanmobility`mob'
*** Main effect of post is subsumed by FEs
areg meanmobility treatment_post treatment [aweight=minsample*coeffyweight], absorb(bin) cluster(country_job)
sort treatment post
by treatment post: summarize meanmobility [aweight=minsample*coeffyweight]
log close
*********************************************************************************************************************************************************
*
* The Effect of Regulatory Harmonization on Cross-Border Labor Migration: Evidence from the Accounting Profession
*
* Matthew J. Bloomfield, Ulf Bruggemann, Hans B. Christensen and Christian Leuz
*
* This do-file shows the code for the main empirical analysis presented in Table 3 of the paper.
* The analysis is based on the EU Labour Force Survey (LFS) core data (version: December 2012).
* We use the annual files for 29 European countries for years 2002 to 2004 and 2008 to 2010, respectively.
*
*********************************************************************************************************************************************************
*********************************************************************************************************************************************************
* I. Data preparation
*********************************************************************************************************************************************************
**************************************************************************************************************
* Step 1: Read and clean key LFS items
**************************************************************************************************************
clear
gen country = ""
save BBCL_Data_raw, replace
local varlist at be bg ch cy cz de dk ee es fi fr gr hu ie is it lt lu lv nl no pl pt ro se si sk uk
qui foreach country of local varlist {
qui foreach year in 2002 2003 2004 2008 2009 2010 {
use EU_LFS_yr_`country'`year', clear
* Clean job code item
tostring isco3d, replace
replace isco3d = "" if isco3d == "."
replace isco3d = "0" if isco3d == "0 0" | isco3d == "010"
destring isco3d, replace
* Clean items related to mobility
tostring countryb national yearesid countr1y, replace
gen countryb_own = (countryb == "OWN COUNTRY" | countryb == "0" | substr(countryb,1,3) == "000")
gen countryb_na = (countryb == "NO ANSWER")
gen national_own = (national == "OWN COUNTRY" | national == "0" | substr(national,1,3) == "000")
gen national_na = (national == "NO ANSWER")
gen source_eu15 = ((countryb == "001-EU15" | countryb == "111") & (national == "001-EU15" | national == "111"))
replace yearesid = "NA" if yearesid == "." | yearesid == ""
replace yearesid = substr(yearesid,2,length(yearesid)-1) if substr(yearesid,1,1) == "0" & yearesid != "0"
gen countr1y_own = (countr1y == country)
gen countr1y_na = (countr1y == "NO ANSWER" | countr1y == "." | countr1y == "" | countr1y == "99" | real(countr1y) <= 14)
* Focus on key LFS items
keep country year isco3d countryb_* national_* source_eu15 yearesid countr1y_* sex age marstat hhlink qhhnum hatlevel hatyear sizefirm startime coeffy
order country year isco3d countryb_* national_* source_eu15 yearesid countr1y_* sex age marstat hhlink qhhnum hatlevel hatyear sizefirm startime coeffy
append using BBCL_Data_raw
compress
save BBCL_Data_raw, replace
}
}
**************************************************************************************************************
* Step 2: Impose sample restrictions and compute key variables
**************************************************************************************************************
use BBCL_Data_raw, clear
* Compute mobility metrics
gen mob_natbirth = (countryb_own == 0 & yearesid != "0" & national_own == 0)
replace mob_natbirth = . if (countryb_na == 1 & yearesid == "NA") | national_na == 1
gen mob_natbirth_eu15 = mob_natbirth
replace mob_natbirth_eu15 = 0 if source_eu15 == 0 & mob_natbirth == 1
gen startime_adj = startime + 6
gen startime_yrs = floor(startime_adj/12)
gen startyear = year - startime_yrs
gen recent = (startyear >= 1999 & year < 2005) | (startyear >= 2005 & year > 2005)
replace recent = . if startyear == .
gen mob_natbirth_chg = (mob_natbirth == 1 & recent == 1)
replace mob_natbirth_chg = . if startyear == . | mob_natbirth==.
gen mob_yearesid = 0
replace mob_yearesid = 1 if ((year == 2004 | year == 2010) & (yearesid == "1" | yearesid == "2" | yearesid == "3" | yearesid == "4" | yearesid == "5"))
replace mob_yearesid = 1 if ((year == 2003 | year == 2009) & (yearesid == "1" | yearesid == "2" | yearesid == "3" | yearesid == "4"))
replace mob_yearesid = 1 if ((year == 2002 | year == 2008) & (yearesid == "1" | yearesid == "2" | yearesid == "3"))
replace mob_yearesid = . if yearesid == "NA" | (year >= 2005 & year <= 2007)
gen mob_countr1y = (countr1y_own != 1)
replace mob_countr1y = . if countr1y_na == 1
* Compute controls
*** Female yes/no
gen female = (sex == 2)
*** Has kids yes/no
gen help = (hhlink == 3) if age < 15
bysort country year qhhnum: egen hhlink3 = sum(help)
bysort country year: egen hhlink3_max = max(hhlink3)
replace hhlink3 = . if hhlink3_max == 0
rename hhlink3 hhkids
gen haskids = (hhkids >= 1)
replace haskids = -1 if hhkids == .
replace haskids = -1 if country == "IE"
/* haskids set to missing for Ireland (see footnote 15 in the paper) */
*** Single yes/no
gen single = (marstat == 1)
replace single = . if marstat ==.
*** Higher education yes/no
gen education_pre = floor(hatlevel/10)
gen education = (education_pre == 5 | education_pre == 6)
replace education = . if education_pre < 3 | education_pre == .
* Sample restrictions
*** Age restriction
keep if age >= 20 & age <= 59
*** Drop countries that do not provide ISCO3D information at three-digit level (see footnote 12 in the paper)
drop if country == "BG" | country == "PL" | country == "SI"
*** Drop professions subject to confounding regulatory treatment
drop if isco3d == 214 | isco3d == 222 | isco3d == 223
* Define samples
gen sample_acc = (isco3d == 241)
gen sample_law = (isco3d == 242)
gen sample_pro = (isco3d >= 200 & isco3d < 300 & isco3d != 241)
gen sample_biz = (isco3d == 121 | isco3d == 122 | isco3d == 123 | isco3d == 131 | isco3d == 341 | isco3d == 342)
keep if sample_acc == 1 | sample_law == 1 | sample_pro == 1 | sample_biz == 1
keep country year sample_* mob_* recent female age haskids single education sizefirm coeffy
compress
save BBCL_Data_clean, replace
*********************************************************************************************************************************************************
* II. Data analysis
*********************************************************************************************************************************************************
log using "BBCL_LM_Code.log", replace
**************************************************************************************************************
* Table 3, Panel A and B: Baseline regressions without/with domestic job mobility control
**************************************************************************************************************
use BBCL_Data_clean, clear
* Prepare regressions
*** Determine regression samples
gen sample_1 = (sample_acc == 1 | sample_law == 1)
gen sample_2 = (sample_acc == 1 | sample_pro == 1)
gen sample_3 = (sample_acc == 1 | sample_biz == 1)
*** Require mob_natbirth and mob_natbirth_chg to be non-missing
keep if mob_natbirth != . & mob_natbirth_chg != .
*** Compute test variables
gen treatment = sample_acc
gen post = (year > 2005)
gen treatment_post = treatment*post
*** Compute domestic job mobility control
qui forvalues i = 1/3 {
gen dom_obs_unwght = 1 if mob_natbirth == 0 & sample_`i' == 1
gen dom_recent_unwght = 1 if mob_natbirth == 0 & recent == 1 & sample_`i' == 1
gen dom_obs_wght = coeffy if mob_natbirth == 0 & sample_`i' == 1
gen dom_recent_wght = coeffy if mob_natbirth == 0 & recent == 1 & sample_`i' == 1
bysort country year treatment: egen help1 = sum(dom_obs_unwght)
bysort country year treatment: egen help2 = sum(dom_recent_unwght)
gen dom_mob_unwght_`i' = (help2/help1)*100
bysort country year treatment: egen help3 = sum(dom_obs_wght)
bysort country year treatment: egen help4 = sum(dom_recent_wght)
gen dom_mob_wght_`i' = (help4/help3)*100
drop dom_obs* dom_recent_* help*
}
*** Prepare fixed effects
egen bin = group(female age single haskids education)
egen country_job = group(country treatment)
egen country_year = group(country year)
* Regressions without domestic job mobility control (Panel A)
forvalues i = 1/3 {
preserve
keep if sample_`i' == 1
keep if coeffy != . & coeffy > 0
reghdfe mob_natbirth treatment_post [aweight = coeffy], absorb(bin country_job country_year) cluster(country_job) keepsingleton
restore
}
forvalues i = 1/3 {
preserve
keep if sample_`i' == 1
reghdfe mob_natbirth treatment_post, absorb(bin country_job country_year) cluster(country_job) keepsingleton
restore
}
forvalues i = 1/3 {
preserve
keep if sample_`i' == 1
keep if coeffy != . & coeffy > 0
reghdfe mob_natbirth_chg treatment_post [aweight = coeffy], absorb(bin country_job country_year) cluster(country_job) keepsingleton
restore
}
forvalues i = 1/3 {
preserve
keep if sample_`i' == 1
reghdfe mob_natbirth_chg treatment_post, absorb(bin country_job country_year) cluster(country_job) keepsingleton
restore
}
* Regressions with domestic job mobility control (Panel B)
forvalues i = 1/3 {
preserve
keep if sample_`i' == 1
keep if coeffy != . & coeffy > 0
rename dom_mob_wght_`i' dom_mob_wght
reghdfe mob_natbirth treatment_post dom_mob_wght [aweight = coeffy], absorb(bin country_job country_year) cluster(country_job) keepsingleton
restore
}
forvalues i = 1/3 {
preserve
keep if sample_`i' == 1
rename dom_mob_unwght_`i' dom_mob_unwght
reghdfe mob_natbirth treatment_post dom_mob_unwght, absorb(bin country_job country_year) cluster(country_job) keepsingleton
restore
}
forvalues i = 1/3 {
preserve
keep if sample_`i' == 1
keep if coeffy != . & coeffy > 0
rename dom_mob_wght_`i' dom_mob_wght
reghdfe mob_natbirth_chg treatment_post dom_mob_wght [aweight = coeffy], absorb(bin country_job country_year) cluster(country_job) keepsingleton
restore
}
forvalues i = 1/3 {
preserve
keep if sample_`i' == 1
rename dom_mob_unwght_`i' dom_mob_unwght
reghdfe mob_natbirth_chg treatment_post dom_mob_unwght, absorb(bin country_job country_year) cluster(country_job) keepsingleton
restore
}
**************************************************************************************************************
* Table 3, Panel C: Double matched diff-in-diff analysis
**************************************************************************************************************
* Double matching
local matchvars single haskids age education female
local controlgroups sample_law sample_pro sample_biz
local mobilitymeasures natbirth natbirth_chg
local onlyrecentyesno 0 1
local coeffyweightsyesno 0 1
qui foreach control in `controlgroups' {
foreach measure in `mobilitymeasures' {
foreach onlyrecent in `onlyrecentyesno' {
foreach coeffyweight in `coeffyweightsyesno' {
use BBCL_Data_clean, clear
*** Require mob_natbirth and mob_natbirth_chg to be non-missing
keep if mob_natbirth != . & mob_natbirth_chg != .
if `onlyrecent'==1 {
keep if recent == 1
}
if `coeffyweight'==1 {
drop if coeffy == 0 | coeffy == .
}
foreach matchvar in `matchvars' {
drop if `matchvar' == .
}
gen mobility = mob_`measure'
keep if mobility != .
gen treatment = sample_acc
gen post = (year > 2005)
gen control = `control'
keep if treatment == 1 | control == 1
*** 2002 matched to 2008
*** 2003 matched to 2009
*** 2004 matched to 2010
gen matchyear = year-6*(post==1)
*** This is for any individual isco3d control group
gen iscontrolpre = control*(1-post)
gen istreatedpre = treatment*(1-post)
gen iscontrolpost = control*post
gen istreatedpost = treatment*post
*** Identify number of obs in each cell
sort country matchyear `matchvars'
by country matchyear `matchvars': egen numcontrolpre = sum(iscontrolpre)
by country matchyear `matchvars': egen numtreatedpre = sum(istreatedpre)
by country matchyear `matchvars': egen numcontrolpost = sum(iscontrolpost)
by country matchyear `matchvars': egen numtreatedpost = sum(istreatedpost)
gen matched = 0
gen matchweight = 0
*** Identify observations in "common-support" (at least 1 obs in pre-treat, post-treat, pre-control and post-control)
replace matched = 1 if numcontrolpre > 0 & numtreatedpre > 0 & numtreatedpost > 0 & numcontrolpost > 0
*** Matched accountants in pre-period get a weight of 1. Everyone else gets the required "balancing" weight.
replace matchweight = 1 if treatment == 1 & matched == 1 & post == 0
replace matchweight = numtreatedpre/numcontrolpre if control == 1 & matched == 1 & post == 0
replace matchweight = numtreatedpre/numcontrolpost if control == 1 & matched == 1 & post == 1
replace matchweight = numtreatedpre/numtreatedpost if treatment == 1 & matched == 1 & post == 1
*** Check your work: only difference should be number of observations
*** Weights of all should be equal to number of observations for pre-period accountants
noisily summarize `matchvars' [aweight=matchweight] if treatment == 1 & post == 0
noisily summarize `matchvars' [aweight=matchweight] if treatment == 1 & post == 1
noisily summarize `matchvars' [aweight=matchweight] if control == 1 & post == 0
noisily summarize `matchvars' [aweight=matchweight] if control == 1 & post == 1
*** Keep only matched observations
keep if matched == 1
noisily save "doublematchedsample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", replace
}
}
}
}
*** Doublematched country-matchyear-matchvariable-level analysis (NATBIRTH)
qui foreach control in `controlgroups' {
foreach measure in `mobilitymeasures' {
foreach onlyrecent in `onlyrecentyesno' {
foreach coeffyweight in `coeffyweightsyesno' {
*** Aggregate coeffy-weights by match bin
use "doublematchedsample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
statsby meancoeffy=r(mean) sample=r(N), by(`matchvars' country matchyear) nodots clear: summarize coeffy [aweight=matchweight]
gen coeffyweight=meancoeffy*sample
keep `matchvars' country matchyear coeffyweight
save "coeffyweights.dta", replace
use "doublematchedsample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
*** Aggregate mobility by match bin
statsby meanmobility = r(mean) sample=r(N), by(`matchvars' country matchyear treatment post) nodots clear: summarize mobility
sort `matchvars' country matchyear treatment
*** Calculate sample of smallest bin without each double-matched quadruplet
*** This will be the statistical weighting on the quadruplets diff-in-diff
by `matchvars' country matchyear: egen minsample = min(sample)
by `matchvars' country matchyear: egen bincount = count(sample)
drop if bincount != 4
drop if minsample == 0
merge m:1 `matchvars' country matchyear using "coeffyweights.dta", nogenerate
*** Construct binning variables for clustering and FE's----we use 'country_job' for clusters and 'bin' for FE's
egen bin = group(country matchyear post `matchvars')
egen country_job = group(country treatment)
noisily save "readyforregssample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", replace
}
}
}
}
* Difference-in-differences analysis: full sample, NATBIRTH, LFS weighted (no)
local control sample_pro
local measure natbirth
local onlyrecent 0
local coeffyweight 0
use "doublematchedsample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
tabulate treatment
use "readyforregssample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
gen treatment_post = treatment*post
*** Convert mobility to percent
replace meanmobility = 100*meanmobility
rename meanmobility meanmobility`mob'
*** Main effect of post is subsumed by FEs
areg meanmobility treatment_post treatment [aweight=minsample], absorb(bin) cluster(country_job)
sort treatment post
by treatment post: summarize meanmobility [aweight=minsample]
* Difference-in-differences analysis: full sample, NATBIRTH, LFS weighted (yes)
local control sample_pro
local measure natbirth
local onlyrecent 0
local coeffyweight 1
use "doublematchedsample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
tabulate treatment
use "readyforregssample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
gen treatment_post = treatment*post
*** Convert mobility to percent
replace meanmobility=100*meanmobility
rename meanmobility meanmobility`mob'
*** Main effect of post is subsumed by FEs
areg meanmobility treatment_post treatment [aweight=minsample*coeffyweight], absorb(bin) cluster(country_job)
sort treatment post
by treatment post: summarize meanmobility [aweight=minsample*coeffyweight]
* Difference-in-differences analysis: full sample, NATBIRTH_CHG, LFS weighted (no)
local control sample_pro
local measure natbirth_chg
local onlyrecent 0
local coeffyweight 0
use "doublematchedsample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
tabulate treatment
use "readyforregssample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
gen treatment_post = treatment*post
*** Convert mobility to percent
replace meanmobility=100*meanmobility
rename meanmobility meanmobility`mob'
*** Main effect of post is subsumed by FEs
areg meanmobility treatment_post treatment [aweight=minsample], absorb(bin) cluster(country_job)
sort treatment post
by treatment post: summarize meanmobility [aweight=minsample]
* Difference-in-differences analysis: full sample, NATBIRTH_CHG, LFS weighted (yes)
local control sample_pro
local measure natbirth_chg
local onlyrecent 0
local coeffyweight 1
use "doublematchedsample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
tabulate treatment
use "readyforregssample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
gen treatment_post = treatment*post
*** Convert mobility to percent
replace meanmobility=100*meanmobility
rename meanmobility meanmobility`mob'
*** Main effect of post is subsumed by FEs
areg meanmobility treatment_post treatment [aweight=minsample*coeffyweight], absorb(bin) cluster(country_job)
sort treatment post
by treatment post: summarize meanmobility [aweight=minsample*coeffyweight]
* Difference-in-differences analysis: only recent job changers, NATBIRTH, LFS weighted (no)
local control sample_pro
local measure natbirth
local onlyrecent 1
local coeffyweight 0
use "doublematchedsample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
tabulate treatment
use "readyforregssample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
gen treatment_post = treatment*post
*** Convert mobility to percent
replace meanmobility=100*meanmobility
rename meanmobility meanmobility`mob'
*** Main effect of post is subsumed by FEs
areg meanmobility treatment_post treatment [aweight=minsample], absorb(bin) cluster(country_job)
sort treatment post
by treatment post: summarize meanmobility [aweight=minsample]
* Difference-in-differences analysis: only recent job changers, NATBIRTH, LFS weighted (yes)
local control sample_pro
local measure natbirth
local onlyrecent 1
local coeffyweight 1
use "doublematchedsample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
tabulate treatment
use "readyforregssample_`control'_`measure'_onlyrecent`onlyrecent'_coeffyweight`coeffyweight'.dta", clear
gen treatment_post = treatment*post
*** Convert mobility to percent
replace meanmobility = 100*meanmobility
rename meanmobility meanmobility`mob'
*** Main effect of post is subsumed by FEs
areg meanmobility treatment_post treatment [aweight=minsample*coeffyweight], absorb(bin) cluster(country_job)
sort treatment post
by treatment post: summarize meanmobility [aweight=minsample*coeffyweight]
log close
clear
set more off
*************************************************************************************
* to run the code for all our analyses below, the following three datasets are needed
* FINAL_SAMPLE: our main dataset with IPO, EGC, all financial data
* IND_MTB_FF17: Industry M/B and P/E data at the famafrench 17 industry levels
* HIGHTECH: SIC codes for hightech industries
*************************************************************************************
******* TABLE 2: Sumary Statistics
use FINAL_SAMPLE, clear
* three sets of IPO firms
* egcbyrev==1, Actual EGC IPOs "after" the Act
* egcbyrev==0, EGC-qualifying IPOs "before" the Act
* egcbyrev==. (missing), all other IPOs that do not qaulity EGC status
keep if !missing(egcbyrev)
*mean and median difference test results are by default [egcbyrev==0 - egcbyrec==1], so reverse the order on purpose
*to get results for [egcbyrev==1 - egcbyrec==0]
gen reverse_egcbyrev=!egcbyrev
est clear
estpost summ sale sale_CPIadj1 asset booklev ppenet_asset rnd_asset drnd salegr age unprofitable dum_VC ///
proceeds proceeds_CPIadj1 avrg_uwmktsh diffdate dp_p dp_n acctlegalpct wgspreadpct_new totfeepct ir totcost ///
nasdaq90d nreg_filter if egcbyrev==1, detail
esttab using full_summ_byEGC.csv, cell("mean(fmt(2)) p50(lab(median)) count(fmt(0))") label nonumber nonotes eqlabels("") noconstant replace
estpost summ sale sale_CPIadj1 asset booklev ppenet_asset rnd_asset drnd salegr age unprofitable dum_VC ///
proceeds proceeds_CPIadj1 avrg_uwmktsh diffdate dp_p dp_n acctlegalpct wgspreadpct_new totfeepct ir totcost ///
nasdaq90d nreg_filter if egcbyrev==0, detail
esttab using full_summ_byEGC.csv, cell("mean(fmt(2)) p50(lab(median)) count(fmt(0))") label nonumber nonotes eqlabels("") noconstant append
*mean difference test
estpost ttest sale sale_CPIadj1 asset booklev ppenet_asset rnd_asset drnd salegr age unprofitable dum_VC ///
proceeds proceeds_CPIadj1 avrg_uwmktsh diffdate dp_p dp_n wacctlegalpct wgspreadpct_new totfeepct ir totcost ///
nasdaq90d nreg_filter , by(reverse_egcbyrev)
esttab using full_summ_byEGC.csv, cell("b(lab(mean diff) star fmt(2))") nonumber nonotes eqlabels("") noconstant label star(* 0.10 ** 0.05 *** 0.01) append
*median difference test
median sale, by(reverse_egcbyrev)
median sale_CPIadj1, by(reverse_egcbyrev)
median asset, by(reverse_egcbyrev)
median booklev, by(reverse_egcbyrev)
median ppenet_asset, by(reverse_egcbyrev)
median rnd_asset, by(reverse_egcbyrev)
median drnd, by(reverse_egcbyrev)
median salegr, by(reverse_egcbyrev)
median age, by(reverse_egcbyrev)
median unprofitable, by(reverse_egcbyrev)
median dum_VC, by(reverse_egcbyrev)
median proceeds, by(reverse_egcbyrev)
median proceeds_CPIadj1, by(reverse_egcbyrev)
median avrg_uwmktsh, by(reverse_egcbyrev)
median diffdate, by(reverse_egcbyrev)
median dp, by(reverse_egcbyrev)
median dp_p, by(reverse_egcbyrev)
median acctlegalpct, by(reverse_egcbyrev)
median wgspreadpct_new, by(reverse_egcbyrev)
median totfeepct, by(reverse_egcbyrev)
median ir, by(reverse_egcbyrev)
median totcost, by(reverse_egcbyrev)
median nasdaq90d, by(reverse_egcbyrev)
median nreg_filter, by(reverse_egcbyrev)
******* TABLE 3 & 4: Propensity Score Matching + OLS or Diff-in-diff
use FINAL_SAMPLE, clear
keep if !missing(egcbyrev)
drop if missing(acctlegalpct) & egcatipo!=1
drop if missing(wgspreadpct_new) & egcatipo!=1
drop if missing(dp) & egcatipo!=1
gen treated=(src==0)
gen post=(idate>=date("4/5/2012","MDY",2003))
gen treated_post=treated*post
*For matching, we use FF17 instead of FF50
drop famafrench
do famafrench17
joinby famafrench yr qt using IND_MTB_FF17, unmatched(master) update
tab _merge
drop _merge
label var indprc_earn17 "Ind P/E"
bys famafrench: egen negcipos=sum(egcipo)
tab famafrench egcipo
*psmtch for each ff industry
*aggregate several ff industries when those industries do not have enough control IPOs to match with
gen sample=.
foreach i of numlist 7 11 16 17 {
di "famafrench `i'"
psmatch2 egcipo lnproceeds lnsale unprofitable salegr lnage booklev ppenet_asset rnd_asset avrg_brmktsh nasdaq90d indprc_earn17 if famafrench==`i', n(1) logit norepla
replace sample=_weight if famafrench==`i'
}
gen pscore=_pscore
psmatch2 egcipo lnproceeds lnsale unprofitable salegr lnage booklev ppenet_asset rnd_asset avrg_brmktsh nasdaq90d indprc_earn17 if famafrench==1 | famafrench==2 | famafrench==3 | famafrench==5 | famafrench==6 | famafrench==8 | famafrench==12 | famafrench==13 | famafrench==14 | famafrench==15, n(1) logit norepla
replace sample=_weight if famafrench==1 | famafrench==2 | famafrench==3 | famafrench==5 | famafrench==6 | famafrench==8 | famafrench==12 | famafrench==13 | famafrench==14 | famafrench==15
replace pscore=_pscore if famafrench==1 | famafrench==2 | famafrench==3 | famafrench==5 | famafrench==6 | famafrench==8 | famafrench==12 | famafrench==13 | famafrench==14 | famafrench==15
*restrict to the psmatch sample
keep if !missing(sample)
tab egcipo
gen reverse_egcipo=!egcipo
******* TABLE 3, Panel A
est clear
estpost summ lnproceeds lnsale unprofitable salegr lnage booklev ppenet_asset rnd_asset avrg_brmktsh nasdaq90d indprc_earn17 if egcipo==1, detail
esttab using psmmatchedsample.csv, cell("mean(fmt(3)) sd(fmt(3)) min(fmt(3)) p50(lab(median) fmt(3)) max(fmt(3)) count(fmt(0))") label nonumber nonotes eqlabels("") noconstant replace
estpost summ lnproceeds lnsale unprofitable salegr lnage booklev ppenet_asset rnd_asset avrg_brmktsh nasdaq90d indprc_earn17 if egcipo==0, detail
esttab using psmmatchedsample.csv, cell("mean(fmt(3)) sd(fmt(3)) min(fmt(3)) p50(lab(median) fmt(3)) max(fmt(3)) count(fmt(0))") label nonumber nonotes eqlabels("") noconstant append
estpost ttest lnproceeds lnsale unprofitable salegr lnage booklev ppenet_asset rnd_asset avrg_brmktsh nasdaq90d indprc_earn17, by(reverse_egcipo)
esttab using psmmatchedsample.csv, cell("b(lab(mean diff) star fmt(3)) t(lab(t-stat) fmt(2))") nonumber nonotes eqlabels("") noconstant label star(* 0.10 ** 0.05 *** 0.01) append
******* TABLE 3, Panel B: OLS
est clear
eststo: xi: reg totfeepct egcbyrev lnproceeds_res unprofitable drnd lnage avrg_brmktsh lndiffdate nasdaq90d lnnreg_filter crisis i.famafrench if src==0, robust cluster(ff_yr_qt)
eststo: xi: reg totfeepct egcbyrev lnproceeds_res unprofitable drnd lnage avrg_brmktsh lndiffdate nasdaq90d lnnreg_filter crisis i.famafrench if src==1, robust cluster(ff_yr_qt)
eststo: xi: reg ir egcbyrev dp_p dp_n lnproceeds_res unprofitable drnd lnage avrg_brmktsh lndiffdate nasdaq90d lnnreg_filter crisis i.famafrench if src==0, robust cluster(ff_yr_qt)
eststo: xi: reg ir egcbyrev dp_p dp_n lnproceeds_res unprofitable drnd lnage avrg_brmktsh lndiffdate nasdaq90d lnnreg_filter crisis i.famafrench if src==1 , robust cluster(ff_yr_qt)
esttab using psm_ols.csv, pr2 ar2 nonotes eqlabels("") nonumber noconstant replace depvars drop(_I*) star(* 0.10 ** 0.05 *** 0.01) label b(%9.3f)
******* TABLE 4: Diff-in-Diff
est clear
eststo: xi: reg acctlegalpct treated_post treated post lnproceeds_res unprofitable drnd lnage avrg_brmktsh lndiffdate nasdaq90d lnnreg_filter crisis i.famafrench, robust cluster(ff_yr_qt)
eststo: xi: reg wgspreadpct_new treated_post treated post lnproceeds_res unprofitable drnd lnage avrg_brmktsh lndiffdate nasdaq90d lnnreg_filter crisis i.famafrench, robust cluster(ff_yr_qt)
eststo: xi: reg totfeepct treated_post treated post lnproceeds_res unprofitable drnd lnage avrg_brmktsh lndiffdate nasdaq90d lnnreg_filter crisis i.famafrench, robust cluster(ff_yr_qt)
eststo: xi: reg ir treated_post treated post dp_p dp_n lnproceeds_res unprofitable drnd lnage avrg_brmktsh lndiffdate nasdaq90d lnnreg_filter crisis i.famafrench , robust cluster(ff_yr_qt)
eststo: xi: reg totcost treated_post treated post dp_p dp_n lnproceeds_res unprofitable drnd lnage avrg_brmktsh lndiffdate nasdaq90d lnnreg_filter crisis i.famafrench, robust cluster(ff_yr_qt)
esttab using psm_dd.csv, pr2 ar2 nonotes eqlabels("") nonumber noconstant replace depvars star(* 0.10 ** 0.05 *** 0.01) label b(%9.3f)
******* TABLE 5: Regression Discontinuity with SRC (After the Act)
use FINAL_SAMPLE, clear
*restrict the sample to actual EGCs after the Act
keep if egcbyrev==1
gen nosrc=(proceeds>75)
gen x = proceeds-75
gen nosrc_x=nosrc*x
label var nosrc "Non-SRC"
label var x "(Proceeds-75)"
label var nosrc_x "Non-SRC x (Proceeds-75)"
label var ir "Initial Return"
label var proceeds "Proceeds"
est clear
eststo: xi: reg ir nosrc x nosrc_x unprofitable drnd lnage lndiffdate nasdaq90d lnnreg_filter i.famafrench if proceeds>=50 & proceeds<=100, robust cluster(ff_yr_qt)
eststo: xi: reg ir nosrc x nosrc_x unprofitable drnd lnage lndiffdate nasdaq90d lnnreg_filter i.famafrench if proceeds>=30 & proceeds<=120, robust cluster(ff_yr_qt)
eststo: xi: reg ir nosrc x nosrc_x unprofitable drnd lnage lndiffdate nasdaq90d lnnreg_filter i.famafrench if proceeds>=0 & proceeds<=150, robust cluster(ff_yr_qt)
esttab using rd_ir.csv, pr2 ar2 nonotes eqlabels("") nonumber noconstant replace depvars drop(_I*) star(* 0.10 ** 0.05 *** 0.01) label b(%9.3f)
******* Figure 2: McCrary Test of Proceeds
preserve
keep if proceeds>=0 & proceeds<=300
DCdensity proceeds, breakpoint(75) generate(Xj Yj r0 fhat se_fhat)
graph export McCrary.png, replace
restore
******* Figure 3: Regression Discontinuity around SRC Threshold
preserve
drop if ir>100
twoway (scatter ir proceeds, mcolor(gs10) msize(tiny)) ///
(lfit ir proceeds if proceeds<=75, lcolor(navy) lwidth(medthick)) ///
(lfit ir proceeds if proceeds>75, lcolor(maroon) lwidth(medthick)) ///
if proceeds>=50 & proceeds<=100, xline(75, lcolor(gs6) lpattern(dash)) legend(off) xtitle(Proceeds) ytitle(Initial Return (%)) yscale(range(-30,100)) ylabel(-20(20)100)
graph export rd.png, replace
restore
******* TABLE 5: Regression Discontinuity with SRC (Before the Act)
use FINAL_SAMPLE, clear
*restrict the sample to EGC-qualifying IPOs before the Act
keep if egcbyrev==0
gen nosrc=(proceeds>75)
gen x = proceeds-75
gen nosrc_x=nosrc*x
label var nosrc "Non-SRC"
label var x "(Proceeds-75)"
label var nosrc_x "Non-SRC x (Proceeds-75)"
label var ir "Initial Return"
label var proceeds "Proceeds"
est clear
eststo: xi: reg ir nosrc x nosrc_x unprofitable drnd lnage lndiffdate nasdaq90d lnnreg_filter i.famafrench if proceeds>=50 & proceeds<=100, robust cluster(ff_yr_qt)
eststo: xi: reg ir nosrc x nosrc_x unprofitable drnd lnage lndiffdate nasdaq90d lnnreg_filter i.famafrench if proceeds>=30 & proceeds<=120, robust cluster(ff_yr_qt)
eststo: xi: reg ir nosrc x nosrc_x unprofitable drnd lnage lndiffdate nasdaq90d lnnreg_filter i.famafrench if proceeds>=0 & proceeds<=150, robust cluster(ff_yr_qt)
esttab using rd_ir_preAct.csv, pr2 ar2 nonotes eqlabels("") nonumber noconstant replace depvars drop(_I*) star(* 0.10 ** 0.05 *** 0.01) label b(%9.3f)
******* Figure 2: McCrary Test of Proceeds
preserve
keep if proceeds>=0 & proceeds<=300
DCdensity proceeds, breakpoint(75) generate(Xj Yj r0 fhat se_fhat)
graph export McCrary_preAct.png, replace
restore
******* Figure 3: Regression Discontinuity around SRC Threshold
preserve
drop if ir>100
twoway (scatter ir proceeds, mcolor(gs10) msize(tiny)) ///
(lfit ir proceeds if proceeds<=75, lcolor(navy) lwidth(medthick)) ///
(lfit ir proceeds if proceeds>75, lcolor(maroon) lwidth(medthick)) ///
if proceeds>=50 & proceeds<=100, xline(75, lcolor(gs6) lpattern(dash)) legend(off) xtitle(Proceeds) ytitle(Initial Return (%)) yscale(range(-30,100)) ylabel(-20(20)100)
graph export rd_preAct.png, replace
restore
******* Table 6: JOBS Act Provisions
use FINAL_SAMPLE, clear
keep if egcipo==1
gen ttw_yes=1 if testwaters==1 & egcatipo==1
replace ttw_yes=0 if testwaters==0 & egcatipo==1
replace ttw_yes=0 if testwaters==-1 & egcatipo==1
gen ttw_no=1 if testwaters==0 & egcatipo==1
replace ttw_no=0 if testwaters==1 & egcatipo==1
replace ttw_no=0 if testwaters==-1 & egcatipo==1
gen ttw_yesmay=1 if testwaters==1 & egcatipo==1
replace ttw_yesmay=1 if testwaters==-1 & egcatipo==1
replace ttw_yesmay=0 if testwaters==0 & egcatipo==1
gen soxvoted_yes=0
replace soxvoted_yes=1 if sox_yes==1
replace soxvoted_yes=1 if voted_yes==1
gen soxvoted_no=0
replace soxvoted_no=1 if sox_no==1
replace soxvoted_no=1 if voted_no==1
gen soxvoted_yesmay=0
replace soxvoted_yesmay=1 if sox_yes==1
replace soxvoted_yesmay=1 if sox_may==1
replace soxvoted_yesmay=1 if voted_yes==1
replace soxvoted_yesmay=1 if voted_may==1
gen egcchoice_yes=confidential_yes+sox_yes+execcomp_yes+voted_yes+newrule_yes+financial_yes+ttw_yes
gen egcchoice_no=confidential_no+sox_no+execcomp_no+voted_no+newrule_no+financial_no+ttw_no
gen egcchoice_may=sox_may+execcomp_may+voted_may+newrule_may+financial_may
gen egcchoice_yesmay=confidential_yesmay+sox_yesmay+execcomp_yesmay+voted_yesmay+newrule_yesmay+financial_yesmay+ttw_yesmay
gen period=.
replace period=1 if idate>=date("4/5/2012","MDY",2012) & idate<date("4/4/2013","MDY",2012)
replace period=2 if idate>=date("4/5/2013","MDY",2012) & idate<date("4/4/2014","MDY",2012)
replace period=3 if idate>=date("4/5/2014","MDY",2012) & idate<date("4/30/2015","MDY",2012)
tab confidential if egcatipo==1
bys period: tab confidential if egcatipo==1
tab testwaters if egcatipo==1
bys period: tab testwaters if egcatipo==1
tab financial if egcatipo==1
bys period: tab financial if egcatipo==1
tab execcomp if egcatipo==1
bys period: tab execcomp if egcatipo==1
tab sox if egcatipo==1
bys period: tab sox if egcatipo==1
tab voted if egcatipo==1
bys period: tab voted if egcatipo==1
tab newrule if egcatipo==1
bys period: tab newrule if egcatipo==1
tabstat egcchoice_may if egcatipo==1
tabstat egcchoice_may if egcatipo==1, by(period)
tabstat egcchoice_no if egcatipo==1
tabstat egcchoice_no if egcatipo==1, by(period)
tabstat egcchoice_yes if egcatipo==1
tabstat egcchoice_yes if egcatipo==1, by(period)
******* Table 7: Determinants of Disclosure Choices
label var egcchoice_no "Number of 'No' Choices"
joinby sic using HIGHTECH, unmatched(master)
tab _merge
drop _merge
replace hightech=0 if missing(hightech)
drop famafrench
gen famafrench=1
replace famafrench=2 if hightech==1
replace famafrench=3 if dum_biopharma==1
est clear
eststo: xi: reg egcchoice_no lnproceeds_res unprofitable lnage booklev ppenet_asset rnd_asset avrg_brmktsh, robust
eststo: xi: reg egcchoice_no lnproceeds_res unprofitable lnage booklev ppenet_asset rnd_asset avrg_brmktsh i.period, robust
eststo: xi: reg egcchoice_no lnproceeds_res unprofitable lnage booklev ppenet_asset rnd_asset avrg_brmktsh i.famafrench, robust
eststo: xi: reg egcchoice_no lnproceeds_res unprofitable lnage booklev ppenet_asset rnd_asset avrg_brmktsh i.famafrench i.period, robust
esttab using disclosure.csv, pr2 ar2 notes eqlabels("") nonumber replace depvars star(* 0.10 ** 0.05 *** 0.01) label b(%9.3f)
******* Figure 1 & Table 1: Sample of IPOs
use FINAL_SAMPLE, clear
drop mo qt
gen mo=month(idate)
gen qt=1 if mo==1|mo==2|mo==3
replace qt=2 if mo==4|mo==5|mo==6
replace qt=3 if mo==7|mo==8|mo==9
replace qt=4 if mo==10|mo==11|mo==12
gen ipo=1
gen control=(egcbyrev==0)
gen egcc=(egcbyrev==1)
gen nonq=(missing(egcbyrev))
gen nonsrc=(src==0)
collapse (sum) ipo control egcc nonq src nonsrc, by(yr qt)
browse
******* Figure 4: Residual IR
use FINAL_SAMPLE, clear
keep if !missing(egcbyrev)
xi: reg ir dp lnproceeds_res unprofitable lnage avrg_uwmktsh diffdate nasdaq90d nreg_filter crisis i.famafrench, robust cluster(ff_yr_qt)
predict ir_res, res
drop mo qt
gen mo=month(idate)
gen qt=1 if mo==1|mo==2|mo==3
replace qt=2 if mo==4|mo==5|mo==6
replace qt=3 if mo==7|mo==8|mo==9
replace qt=4 if mo==10|mo==11|mo==12
collapse (count) nipos=ir (mean) ir_res, by(yr)
browse
clear
set more off
*************************************************************************************
* to run the code for all our analyses below, the following three datasets are needed
* FINAL_SAMPLE: our main dataset with IPO, EGC, all financial data
* IND_MTB_FF17: Industry M/B and P/E data at the famafrench 17 industry levels
* HIGHTECH: SIC codes for hightech industries
*************************************************************************************
******* TABLE 2: Sumary Statistics
use FINAL_SAMPLE, clear
* three sets of IPO firms
* egcbyrev==1, Actual EGC IPOs "after" the Act
* egcbyrev==0, EGC-qualifying IPOs "before" the Act
* egcbyrev==. (missing), all other IPOs that do not qaulity EGC status
keep if !missing(egcbyrev)
*mean and median difference test results are by default [egcbyrev==0 - egcbyrec==1], so reverse the order on purpose
*to get results for [egcbyrev==1 - egcbyrec==0]
gen reverse_egcbyrev=!egcbyrev
est clear
estpost summ sale sale_CPIadj1 asset booklev ppenet_asset rnd_asset drnd salegr age unprofitable dum_VC ///
proceeds proceeds_CPIadj1 avrg_uwmktsh diffdate dp_p dp_n acctlegalpct wgspreadpct_new totfeepct ir totcost ///
nasdaq90d nreg_filter if egcbyrev==1, detail
esttab using full_summ_byEGC.csv, cell("mean(fmt(2)) p50(lab(median)) count(fmt(0))") label nonumber nonotes eqlabels("") noconstant replace
estpost summ sale sale_CPIadj1 asset booklev ppenet_asset rnd_asset drnd salegr age unprofitable dum_VC ///
proceeds proceeds_CPIadj1 avrg_uwmktsh diffdate dp_p dp_n acctlegalpct wgspreadpct_new totfeepct ir totcost ///
nasdaq90d nreg_filter if egcbyrev==0, detail
esttab using full_summ_byEGC.csv, cell("mean(fmt(2)) p50(lab(median)) count(fmt(0))") label nonumber nonotes eqlabels("") noconstant append
*mean difference test
estpost ttest sale sale_CPIadj1 asset booklev ppenet_asset rnd_asset drnd salegr age unprofitable dum_VC ///
proceeds proceeds_CPIadj1 avrg_uwmktsh diffdate dp_p dp_n wacctlegalpct wgspreadpct_new totfeepct ir totcost ///
nasdaq90d nreg_filter , by(reverse_egcbyrev)
esttab using full_summ_byEGC.csv, cell("b(lab(mean diff) star fmt(2))") nonumber nonotes eqlabels("") noconstant label star(* 0.10 ** 0.05 *** 0.01) append
*median difference test
median sale, by(reverse_egcbyrev)
median sale_CPIadj1, by(reverse_egcbyrev)
median asset, by(reverse_egcbyrev)
median booklev, by(reverse_egcbyrev)
median ppenet_asset, by(reverse_egcbyrev)
median rnd_asset, by(reverse_egcbyrev)
median drnd, by(reverse_egcbyrev)
median salegr, by(reverse_egcbyrev)
median age, by(reverse_egcbyrev)
median unprofitable, by(reverse_egcbyrev)
median dum_VC, by(reverse_egcbyrev)
median proceeds, by(reverse_egcbyrev)
median proceeds_CPIadj1, by(reverse_egcbyrev)
median avrg_uwmktsh, by(reverse_egcbyrev)
median diffdate, by(reverse_egcbyrev)
median dp, by(reverse_egcbyrev)
median dp_p, by(reverse_egcbyrev)
median acctlegalpct, by(reverse_egcbyrev)
median wgspreadpct_new, by(reverse_egcbyrev)
median totfeepct, by(reverse_egcbyrev)
median ir, by(reverse_egcbyrev)
median totcost, by(reverse_egcbyrev)
median nasdaq90d, by(reverse_egcbyrev)
median nreg_filter, by(reverse_egcbyrev)
******* TABLE 3 & 4: Propensity Score Matching + OLS or Diff-in-diff
use FINAL_SAMPLE, clear
keep if !missing(egcbyrev)
drop if missing(acctlegalpct) & egcatipo!=1
drop if missing(wgspreadpct_new) & egcatipo!=1
drop if missing(dp) & egcatipo!=1
gen treated=(src==0)
gen post=(idate>=date("4/5/2012","MDY",2003))
gen treated_post=treated*post
*For matching, we use FF17 instead of FF50
drop famafrench
do famafrench17
joinby famafrench yr qt using IND_MTB_FF17, unmatched(master) update
tab _merge
drop _merge
label var indprc_earn17 "Ind P/E"
bys famafrench: egen negcipos=sum(egcipo)
tab famafrench egcipo
*psmtch for each ff industry
*aggregate several ff industries when those industries do not have enough control IPOs to match with
gen sample=.
foreach i of numlist 7 11 16 17 {
di "famafrench `i'"
psmatch2 egcipo lnproceeds lnsale unprofitable salegr lnage booklev ppenet_asset rnd_asset avrg_brmktsh nasdaq90d indprc_earn17 if famafrench==`i', n(1) logit norepla
replace sample=_weight if famafrench==`i'
}
gen pscore=_pscore
psmatch2 egcipo lnproceeds lnsale unprofitable salegr lnage booklev ppenet_asset rnd_asset avrg_brmktsh nasdaq90d indprc_earn17 if famafrench==1 | famafrench==2 | famafrench==3 | famafrench==5 | famafrench==6 | famafrench==8 | famafrench==12 | famafrench==13 | famafrench==14 | famafrench==15, n(1) logit norepla
replace sample=_weight if famafrench==1 | famafrench==2 | famafrench==3 | famafrench==5 | famafrench==6 | famafrench==8 | famafrench==12 | famafrench==13 | famafrench==14 | famafrench==15
replace pscore=_pscore if famafrench==1 | famafrench==2 | famafrench==3 | famafrench==5 | famafrench==6 | famafrench==8 | famafrench==12 | famafrench==13 | famafrench==14 | famafrench==15
*restrict to the psmatch sample
keep if !missing(sample)
tab egcipo
gen reverse_egcipo=!egcipo
******* TABLE 3, Panel A
est clear
estpost summ lnproceeds lnsale unprofitable salegr lnage booklev ppenet_asset rnd_asset avrg_brmktsh nasdaq90d indprc_earn17 if egcipo==1, detail
esttab using psmmatchedsample.csv, cell("mean(fmt(3)) sd(fmt(3)) min(fmt(3)) p50(lab(median) fmt(3)) max(fmt(3)) count(fmt(0))") label nonumber nonotes eqlabels("") noconstant replace
estpost summ lnproceeds lnsale unprofitable salegr lnage booklev ppenet_asset rnd_asset avrg_brmktsh nasdaq90d indprc_earn17 if egcipo==0, detail
esttab using psmmatchedsample.csv, cell("mean(fmt(3)) sd(fmt(3)) min(fmt(3)) p50(lab(median) fmt(3)) max(fmt(3)) count(fmt(0))") label nonumber nonotes eqlabels("") noconstant append
estpost ttest lnproceeds lnsale unprofitable salegr lnage booklev ppenet_asset rnd_asset avrg_brmktsh nasdaq90d indprc_earn17, by(reverse_egcipo)
esttab using psmmatchedsample.csv, cell("b(lab(mean diff) star fmt(3)) t(lab(t-stat) fmt(2))") nonumber nonotes eqlabels("") noconstant label star(* 0.10 ** 0.05 *** 0.01) append
******* TABLE 3, Panel B: OLS
est clear
eststo: xi: reg totfeepct egcbyrev lnproceeds_res unprofitable drnd lnage avrg_brmktsh lndiffdate nasdaq90d lnnreg_filter crisis i.famafrench if src==0, robust cluster(ff_yr_qt)
eststo: xi: reg totfeepct egcbyrev lnproceeds_res unprofitable drnd lnage avrg_brmktsh lndiffdate nasdaq90d lnnreg_filter crisis i.famafrench if src==1, robust cluster(ff_yr_qt)
eststo: xi: reg ir egcbyrev dp_p dp_n lnproceeds_res unprofitable drnd lnage avrg_brmktsh lndiffdate nasdaq90d lnnreg_filter crisis i.famafrench if src==0, robust cluster(ff_yr_qt)
eststo: xi: reg ir egcbyrev dp_p dp_n lnproceeds_res unprofitable drnd lnage avrg_brmktsh lndiffdate nasdaq90d lnnreg_filter crisis i.famafrench if src==1 , robust cluster(ff_yr_qt)
esttab using psm_ols.csv, pr2 ar2 nonotes eqlabels("") nonumber noconstant replace depvars drop(_I*) star(* 0.10 ** 0.05 *** 0.01) label b(%9.3f)
******* TABLE 4: Diff-in-Diff
est clear
eststo: xi: reg acctlegalpct treated_post treated post lnproceeds_res unprofitable drnd lnage avrg_brmktsh lndiffdate nasdaq90d lnnreg_filter crisis i.famafrench, robust cluster(ff_yr_qt)
eststo: xi: reg wgspreadpct_new treated_post treated post lnproceeds_res unprofitable drnd lnage avrg_brmktsh lndiffdate nasdaq90d lnnreg_filter crisis i.famafrench, robust cluster(ff_yr_qt)
eststo: xi: reg totfeepct treated_post treated post lnproceeds_res unprofitable drnd lnage avrg_brmktsh lndiffdate nasdaq90d lnnreg_filter crisis i.famafrench, robust cluster(ff_yr_qt)
eststo: xi: reg ir treated_post treated post dp_p dp_n lnproceeds_res unprofitable drnd lnage avrg_brmktsh lndiffdate nasdaq90d lnnreg_filter crisis i.famafrench , robust cluster(ff_yr_qt)
eststo: xi: reg totcost treated_post treated post dp_p dp_n lnproceeds_res unprofitable drnd lnage avrg_brmktsh lndiffdate nasdaq90d lnnreg_filter crisis i.famafrench, robust cluster(ff_yr_qt)
esttab using psm_dd.csv, pr2 ar2 nonotes eqlabels("") nonumber noconstant replace depvars star(* 0.10 ** 0.05 *** 0.01) label b(%9.3f)
******* TABLE 5: Regression Discontinuity with SRC (After the Act)
use FINAL_SAMPLE, clear
*restrict the sample to actual EGCs after the Act
keep if egcbyrev==1
gen nosrc=(proceeds>75)
gen x = proceeds-75
gen nosrc_x=nosrc*x
label var nosrc "Non-SRC"
label var x "(Proceeds-75)"
label var nosrc_x "Non-SRC x (Proceeds-75)"
label var ir "Initial Return"
label var proceeds "Proceeds"
est clear
eststo: xi: reg ir nosrc x nosrc_x unprofitable drnd lnage lndiffdate nasdaq90d lnnreg_filter i.famafrench if proceeds>=50 & proceeds<=100, robust cluster(ff_yr_qt)
eststo: xi: reg ir nosrc x nosrc_x unprofitable drnd lnage lndiffdate nasdaq90d lnnreg_filter i.famafrench if proceeds>=30 & proceeds<=120, robust cluster(ff_yr_qt)
eststo: xi: reg ir nosrc x nosrc_x unprofitable drnd lnage lndiffdate nasdaq90d lnnreg_filter i.famafrench if proceeds>=0 & proceeds<=150, robust cluster(ff_yr_qt)
esttab using rd_ir.csv, pr2 ar2 nonotes eqlabels("") nonumber noconstant replace depvars drop(_I*) star(* 0.10 ** 0.05 *** 0.01) label b(%9.3f)
******* Figure 2: McCrary Test of Proceeds
preserve
keep if proceeds>=0 & proceeds<=300
DCdensity proceeds, breakpoint(75) generate(Xj Yj r0 fhat se_fhat)
graph export McCrary.png, replace
restore
******* Figure 3: Regression Discontinuity around SRC Threshold
preserve
drop if ir>100
twoway (scatter ir proceeds, mcolor(gs10) msize(tiny)) ///
(lfit ir proceeds if proceeds<=75, lcolor(navy) lwidth(medthick)) ///
(lfit ir proceeds if proceeds>75, lcolor(maroon) lwidth(medthick)) ///
if proceeds>=50 & proceeds<=100, xline(75, lcolor(gs6) lpattern(dash)) legend(off) xtitle(Proceeds) ytitle(Initial Return (%)) yscale(range(-30,100)) ylabel(-20(20)100)
graph export rd.png, replace
restore
******* TABLE 5: Regression Discontinuity with SRC (Before the Act)
use FINAL_SAMPLE, clear
*restrict the sample to EGC-qualifying IPOs before the Act
keep if egcbyrev==0
gen nosrc=(proceeds>75)
gen x = proceeds-75
gen nosrc_x=nosrc*x
label var nosrc "Non-SRC"
label var x "(Proceeds-75)"
label var nosrc_x "Non-SRC x (Proceeds-75)"
label var ir "Initial Return"
label var proceeds "Proceeds"
est clear
eststo: xi: reg ir nosrc x nosrc_x unprofitable drnd lnage lndiffdate nasdaq90d lnnreg_filter i.famafrench if proceeds>=50 & proceeds<=100, robust cluster(ff_yr_qt)
eststo: xi: reg ir nosrc x nosrc_x unprofitable drnd lnage lndiffdate nasdaq90d lnnreg_filter i.famafrench if proceeds>=30 & proceeds<=120, robust cluster(ff_yr_qt)
eststo: xi: reg ir nosrc x nosrc_x unprofitable drnd lnage lndiffdate nasdaq90d lnnreg_filter i.famafrench if proceeds>=0 & proceeds<=150, robust cluster(ff_yr_qt)
esttab using rd_ir_preAct.csv, pr2 ar2 nonotes eqlabels("") nonumber noconstant replace depvars drop(_I*) star(* 0.10 ** 0.05 *** 0.01) label b(%9.3f)
******* Figure 2: McCrary Test of Proceeds
preserve
keep if proceeds>=0 & proceeds<=300
DCdensity proceeds, breakpoint(75) generate(Xj Yj r0 fhat se_fhat)
graph export McCrary_preAct.png, replace
restore
******* Figure 3: Regression Discontinuity around SRC Threshold
preserve
drop if ir>100
twoway (scatter ir proceeds, mcolor(gs10) msize(tiny)) ///
(lfit ir proceeds if proceeds<=75, lcolor(navy) lwidth(medthick)) ///
(lfit ir proceeds if proceeds>75, lcolor(maroon) lwidth(medthick)) ///
if proceeds>=50 & proceeds<=100, xline(75, lcolor(gs6) lpattern(dash)) legend(off) xtitle(Proceeds) ytitle(Initial Return (%)) yscale(range(-30,100)) ylabel(-20(20)100)
graph export rd_preAct.png, replace
restore
******* Table 6: JOBS Act Provisions
use FINAL_SAMPLE, clear
keep if egcipo==1
gen ttw_yes=1 if testwaters==1 & egcatipo==1
replace ttw_yes=0 if testwaters==0 & egcatipo==1
replace ttw_yes=0 if testwaters==-1 & egcatipo==1
gen ttw_no=1 if testwaters==0 & egcatipo==1
replace ttw_no=0 if testwaters==1 & egcatipo==1
replace ttw_no=0 if testwaters==-1 & egcatipo==1
gen ttw_yesmay=1 if testwaters==1 & egcatipo==1
replace ttw_yesmay=1 if testwaters==-1 & egcatipo==1
replace ttw_yesmay=0 if testwaters==0 & egcatipo==1
gen soxvoted_yes=0
replace soxvoted_yes=1 if sox_yes==1
replace soxvoted_yes=1 if voted_yes==1
gen soxvoted_no=0
replace soxvoted_no=1 if sox_no==1
replace soxvoted_no=1 if voted_no==1
gen soxvoted_yesmay=0
replace soxvoted_yesmay=1 if sox_yes==1
replace soxvoted_yesmay=1 if sox_may==1
replace soxvoted_yesmay=1 if voted_yes==1
replace soxvoted_yesmay=1 if voted_may==1
gen egcchoice_yes=confidential_yes+sox_yes+execcomp_yes+voted_yes+newrule_yes+financial_yes+ttw_yes
gen egcchoice_no=confidential_no+sox_no+execcomp_no+voted_no+newrule_no+financial_no+ttw_no
gen egcchoice_may=sox_may+execcomp_may+voted_may+newrule_may+financial_may
gen egcchoice_yesmay=confidential_yesmay+sox_yesmay+execcomp_yesmay+voted_yesmay+newrule_yesmay+financial_yesmay+ttw_yesmay
gen period=.
replace period=1 if idate>=date("4/5/2012","MDY",2012) & idate<date("4/4/2013","MDY",2012)
replace period=2 if idate>=date("4/5/2013","MDY",2012) & idate<date("4/4/2014","MDY",2012)
replace period=3 if idate>=date("4/5/2014","MDY",2012) & idate<date("4/30/2015","MDY",2012)
tab confidential if egcatipo==1
bys period: tab confidential if egcatipo==1
tab testwaters if egcatipo==1
bys period: tab testwaters if egcatipo==1
tab financial if egcatipo==1
bys period: tab financial if egcatipo==1
tab execcomp if egcatipo==1
bys period: tab execcomp if egcatipo==1
tab sox if egcatipo==1
bys period: tab sox if egcatipo==1
tab voted if egcatipo==1
bys period: tab voted if egcatipo==1
tab newrule if egcatipo==1
bys period: tab newrule if egcatipo==1
tabstat egcchoice_may if egcatipo==1
tabstat egcchoice_may if egcatipo==1, by(period)
tabstat egcchoice_no if egcatipo==1
tabstat egcchoice_no if egcatipo==1, by(period)
tabstat egcchoice_yes if egcatipo==1
tabstat egcchoice_yes if egcatipo==1, by(period)
******* Table 7: Determinants of Disclosure Choices
label var egcchoice_no "Number of 'No' Choices"
joinby sic using HIGHTECH, unmatched(master)
tab _merge
drop _merge
replace hightech=0 if missing(hightech)
drop famafrench
gen famafrench=1
replace famafrench=2 if hightech==1
replace famafrench=3 if dum_biopharma==1
est clear
eststo: xi: reg egcchoice_no lnproceeds_res unprofitable lnage booklev ppenet_asset rnd_asset avrg_brmktsh, robust
eststo: xi: reg egcchoice_no lnproceeds_res unprofitable lnage booklev ppenet_asset rnd_asset avrg_brmktsh i.period, robust
eststo: xi: reg egcchoice_no lnproceeds_res unprofitable lnage booklev ppenet_asset rnd_asset avrg_brmktsh i.famafrench, robust
eststo: xi: reg egcchoice_no lnproceeds_res unprofitable lnage booklev ppenet_asset rnd_asset avrg_brmktsh i.famafrench i.period, robust
esttab using disclosure.csv, pr2 ar2 notes eqlabels("") nonumber replace depvars star(* 0.10 ** 0.05 *** 0.01) label b(%9.3f)
******* Figure 1 & Table 1: Sample of IPOs
use FINAL_SAMPLE, clear
drop mo qt
gen mo=month(idate)
gen qt=1 if mo==1|mo==2|mo==3
replace qt=2 if mo==4|mo==5|mo==6
replace qt=3 if mo==7|mo==8|mo==9
replace qt=4 if mo==10|mo==11|mo==12
gen ipo=1
gen control=(egcbyrev==0)
gen egcc=(egcbyrev==1)
gen nonq=(missing(egcbyrev))
gen nonsrc=(src==0)
collapse (sum) ipo control egcc nonq src nonsrc, by(yr qt)
browse
******* Figure 4: Residual IR
use FINAL_SAMPLE, clear
keep if !missing(egcbyrev)
xi: reg ir dp lnproceeds_res unprofitable lnage avrg_uwmktsh diffdate nasdaq90d nreg_filter crisis i.famafrench, robust cluster(ff_yr_qt)
predict ir_res, res
drop mo qt
gen mo=month(idate)
gen qt=1 if mo==1|mo==2|mo==3
replace qt=2 if mo==4|mo==5|mo==6
replace qt=3 if mo==7|mo==8|mo==9
replace qt=4 if mo==10|mo==11|mo==12
collapse (count) nipos=ir (mean) ir_res, by(yr)
browse
clear
set more off
*************************************************************************************
* to run the code for all our analyses below, the following three datasets are needed
* FINAL_SAMPLE: our main dataset with IPO, EGC, all financial data
* IND_MTB_FF17: Industry M/B and P/E data at the famafrench 17 industry levels
* HIGHTECH: SIC codes for hightech industries
*************************************************************************************
******* TABLE 2: Sumary Statistics
use FINAL_SAMPLE, clear
* three sets of IPO firms
* egcbyrev==1, Actual EGC IPOs "after" the Act
* egcbyrev==0, EGC-qualifying IPOs "before" the Act
* egcbyrev==. (missing), all other IPOs that do not qaulity EGC status
keep if !missing(egcbyrev)
*mean and median difference test results are by default [egcbyrev==0 - egcbyrec==1], so reverse the order on purpose
*to get results for [egcbyrev==1 - egcbyrec==0]
gen reverse_egcbyrev=!egcbyrev
est clear
estpost summ sale sale_CPIadj1 asset booklev ppenet_asset rnd_asset drnd salegr age unprofitable dum_VC ///
proceeds proceeds_CPIadj1 avrg_uwmktsh diffdate dp_p dp_n acctlegalpct wgspreadpct_new totfeepct ir totcost ///
nasdaq90d nreg_filter if egcbyrev==1, detail
esttab using full_summ_byEGC.csv, cell("mean(fmt(2)) p50(lab(median)) count(fmt(0))") label nonumber nonotes eqlabels("") noconstant replace
estpost summ sale sale_CPIadj1 asset booklev ppenet_asset rnd_asset drnd salegr age unprofitable dum_VC ///
proceeds proceeds_CPIadj1 avrg_uwmktsh diffdate dp_p dp_n acctlegalpct wgspreadpct_new totfeepct ir totcost ///
nasdaq90d nreg_filter if egcbyrev==0, detail
esttab using full_summ_byEGC.csv, cell("mean(fmt(2)) p50(lab(median)) count(fmt(0))") label nonumber nonotes eqlabels("") noconstant append
*mean difference test
estpost ttest sale sale_CPIadj1 asset booklev ppenet_asset rnd_asset drnd salegr age unprofitable dum_VC ///
proceeds proceeds_CPIadj1 avrg_uwmktsh diffdate dp_p dp_n wacctlegalpct wgspreadpct_new totfeepct ir totcost ///
nasdaq90d nreg_filter , by(reverse_egcbyrev)
esttab using full_summ_byEGC.csv, cell("b(lab(mean diff) star fmt(2))") nonumber nonotes eqlabels("") noconstant label star(* 0.10 ** 0.05 *** 0.01) append
*median difference test
median sale, by(reverse_egcbyrev)
median sale_CPIadj1, by(reverse_egcbyrev)
median asset, by(reverse_egcbyrev)
median booklev, by(reverse_egcbyrev)
median ppenet_asset, by(reverse_egcbyrev)
median rnd_asset, by(reverse_egcbyrev)
median drnd, by(reverse_egcbyrev)
median salegr, by(reverse_egcbyrev)
median age, by(reverse_egcbyrev)
median unprofitable, by(reverse_egcbyrev)
median dum_VC, by(reverse_egcbyrev)
median proceeds, by(reverse_egcbyrev)
median proceeds_CPIadj1, by(reverse_egcbyrev)
median avrg_uwmktsh, by(reverse_egcbyrev)
median diffdate, by(reverse_egcbyrev)
median dp, by(reverse_egcbyrev)
median dp_p, by(reverse_egcbyrev)
median acctlegalpct, by(reverse_egcbyrev)
median wgspreadpct_new, by(reverse_egcbyrev)
median totfeepct, by(reverse_egcbyrev)
median ir, by(reverse_egcbyrev)
median totcost, by(reverse_egcbyrev)
median nasdaq90d, by(reverse_egcbyrev)
median nreg_filter, by(reverse_egcbyrev)
******* TABLE 3 & 4: Propensity Score Matching + OLS or Diff-in-diff
use FINAL_SAMPLE, clear
keep if !missing(egcbyrev)
drop if missing(acctlegalpct) & egcatipo!=1
drop if missing(wgspreadpct_new) & egcatipo!=1
drop if missing(dp) & egcatipo!=1
gen treated=(src==0)
gen post=(idate>=date("4/5/2012","MDY",2003))
gen treated_post=treated*post
*For matching, we use FF17 instead of FF50
drop famafrench
do famafrench17
joinby famafrench yr qt using IND_MTB_FF17, unmatched(master) update
tab _merge
drop _merge
label var indprc_earn17 "Ind P/E"
bys famafrench: egen negcipos=sum(egcipo)
tab famafrench egcipo
*psmtch for each ff industry
*aggregate several ff industries when those industries do not have enough control IPOs to match with
gen sample=.
foreach i of numlist 7 11 16 17 {
di "famafrench `i'"
psmatch2 egcipo lnproceeds lnsale unprofitable salegr lnage booklev ppenet_asset rnd_asset avrg_brmktsh nasdaq90d indprc_earn17 if famafrench==`i', n(1) logit norepla
replace sample=_weight if famafrench==`i'
}
gen pscore=_pscore
psmatch2 egcipo lnproceeds lnsale unprofitable salegr lnage booklev ppenet_asset rnd_asset avrg_brmktsh nasdaq90d indprc_earn17 if famafrench==1 | famafrench==2 | famafrench==3 | famafrench==5 | famafrench==6 | famafrench==8 | famafrench==12 | famafrench==13 | famafrench==14 | famafrench==15, n(1) logit norepla
replace sample=_weight if famafrench==1 | famafrench==2 | famafrench==3 | famafrench==5 | famafrench==6 | famafrench==8 | famafrench==12 | famafrench==13 | famafrench==14 | famafrench==15
replace pscore=_pscore if famafrench==1 | famafrench==2 | famafrench==3 | famafrench==5 | famafrench==6 | famafrench==8 | famafrench==12 | famafrench==13 | famafrench==14 | famafrench==15
*restrict to the psmatch sample
keep if !missing(sample)
tab egcipo
gen reverse_egcipo=!egcipo
******* TABLE 3, Panel A
est clear
estpost summ lnproceeds lnsale unprofitable salegr lnage booklev ppenet_asset rnd_asset avrg_brmktsh nasdaq90d indprc_earn17 if egcipo==1, detail
esttab using psmmatchedsample.csv, cell("mean(fmt(3)) sd(fmt(3)) min(fmt(3)) p50(lab(median) fmt(3)) max(fmt(3)) count(fmt(0))") label nonumber nonotes eqlabels("") noconstant replace
estpost summ lnproceeds lnsale unprofitable salegr lnage booklev ppenet_asset rnd_asset avrg_brmktsh nasdaq90d indprc_earn17 if egcipo==0, detail
esttab using psmmatchedsample.csv, cell("mean(fmt(3)) sd(fmt(3)) min(fmt(3)) p50(lab(median) fmt(3)) max(fmt(3)) count(fmt(0))") label nonumber nonotes eqlabels("") noconstant append
estpost ttest lnproceeds lnsale unprofitable salegr lnage booklev ppenet_asset rnd_asset avrg_brmktsh nasdaq90d indprc_earn17, by(reverse_egcipo)
esttab using psmmatchedsample.csv, cell("b(lab(mean diff) star fmt(3)) t(lab(t-stat) fmt(2))") nonumber nonotes eqlabels("") noconstant label star(* 0.10 ** 0.05 *** 0.01) append
******* TABLE 3, Panel B: OLS
est clear
eststo: xi: reg totfeepct egcbyrev lnproceeds_res unprofitable drnd lnage avrg_brmktsh lndiffdate nasdaq90d lnnreg_filter crisis i.famafrench if src==0, robust cluster(ff_yr_qt)
eststo: xi: reg totfeepct egcbyrev lnproceeds_res unprofitable drnd lnage avrg_brmktsh lndiffdate nasdaq90d lnnreg_filter crisis i.famafrench if src==1, robust cluster(ff_yr_qt)
eststo: xi: reg ir egcbyrev dp_p dp_n lnproceeds_res unprofitable drnd lnage avrg_brmktsh lndiffdate nasdaq90d lnnreg_filter crisis i.famafrench if src==0, robust cluster(ff_yr_qt)
eststo: xi: reg ir egcbyrev dp_p dp_n lnproceeds_res unprofitable drnd lnage avrg_brmktsh lndiffdate nasdaq90d lnnreg_filter crisis i.famafrench if src==1 , robust cluster(ff_yr_qt)
esttab using psm_ols.csv, pr2 ar2 nonotes eqlabels("") nonumber noconstant replace depvars drop(_I*) star(* 0.10 ** 0.05 *** 0.01) label b(%9.3f)
******* TABLE 4: Diff-in-Diff
est clear
eststo: xi: reg acctlegalpct treated_post treated post lnproceeds_res unprofitable drnd lnage avrg_brmktsh lndiffdate nasdaq90d lnnreg_filter crisis i.famafrench, robust cluster(ff_yr_qt)
eststo: xi: reg wgspreadpct_new treated_post treated post lnproceeds_res unprofitable drnd lnage avrg_brmktsh lndiffdate nasdaq90d lnnreg_filter crisis i.famafrench, robust cluster(ff_yr_qt)
eststo: xi: reg totfeepct treated_post treated post lnproceeds_res unprofitable drnd lnage avrg_brmktsh lndiffdate nasdaq90d lnnreg_filter crisis i.famafrench, robust cluster(ff_yr_qt)
eststo: xi: reg ir treated_post treated post dp_p dp_n lnproceeds_res unprofitable drnd lnage avrg_brmktsh lndiffdate nasdaq90d lnnreg_filter crisis i.famafrench , robust cluster(ff_yr_qt)
eststo: xi: reg totcost treated_post treated post dp_p dp_n lnproceeds_res unprofitable drnd lnage avrg_brmktsh lndiffdate nasdaq90d lnnreg_filter crisis i.famafrench, robust cluster(ff_yr_qt)
esttab using psm_dd.csv, pr2 ar2 nonotes eqlabels("") nonumber noconstant replace depvars star(* 0.10 ** 0.05 *** 0.01) label b(%9.3f)
******* TABLE 5: Regression Discontinuity with SRC (After the Act)
use FINAL_SAMPLE, clear
*restrict the sample to actual EGCs after the Act
keep if egcbyrev==1
gen nosrc=(proceeds>75)
gen x = proceeds-75
gen nosrc_x=nosrc*x
label var nosrc "Non-SRC"
label var x "(Proceeds-75)"
label var nosrc_x "Non-SRC x (Proceeds-75)"
label var ir "Initial Return"
label var proceeds "Proceeds"
est clear
eststo: xi: reg ir nosrc x nosrc_x unprofitable drnd lnage lndiffdate nasdaq90d lnnreg_filter i.famafrench if proceeds>=50 & proceeds<=100, robust cluster(ff_yr_qt)
eststo: xi: reg ir nosrc x nosrc_x unprofitable drnd lnage lndiffdate nasdaq90d lnnreg_filter i.famafrench if proceeds>=30 & proceeds<=120, robust cluster(ff_yr_qt)
eststo: xi: reg ir nosrc x nosrc_x unprofitable drnd lnage lndiffdate nasdaq90d lnnreg_filter i.famafrench if proceeds>=0 & proceeds<=150, robust cluster(ff_yr_qt)
esttab using rd_ir.csv, pr2 ar2 nonotes eqlabels("") nonumber noconstant replace depvars drop(_I*) star(* 0.10 ** 0.05 *** 0.01) label b(%9.3f)
******* Figure 2: McCrary Test of Proceeds
preserve
keep if proceeds>=0 & proceeds<=300
DCdensity proceeds, breakpoint(75) generate(Xj Yj r0 fhat se_fhat)
graph export McCrary.png, replace
restore
******* Figure 3: Regression Discontinuity around SRC Threshold
preserve
drop if ir>100
twoway (scatter ir proceeds, mcolor(gs10) msize(tiny)) ///
(lfit ir proceeds if proceeds<=75, lcolor(navy) lwidth(medthick)) ///
(lfit ir proceeds if proceeds>75, lcolor(maroon) lwidth(medthick)) ///
if proceeds>=50 & proceeds<=100, xline(75, lcolor(gs6) lpattern(dash)) legend(off) xtitle(Proceeds) ytitle(Initial Return (%)) yscale(range(-30,100)) ylabel(-20(20)100)
graph export rd.png, replace
restore
******* TABLE 5: Regression Discontinuity with SRC (Before the Act)
use FINAL_SAMPLE, clear
*restrict the sample to EGC-qualifying IPOs before the Act
keep if egcbyrev==0
gen nosrc=(proceeds>75)
gen x = proceeds-75
gen nosrc_x=nosrc*x
label var nosrc "Non-SRC"
label var x "(Proceeds-75)"
label var nosrc_x "Non-SRC x (Proceeds-75)"
label var ir "Initial Return"
label var proceeds "Proceeds"
est clear
eststo: xi: reg ir nosrc x nosrc_x unprofitable drnd lnage lndiffdate nasdaq90d lnnreg_filter i.famafrench if proceeds>=50 & proceeds<=100, robust cluster(ff_yr_qt)
eststo: xi: reg ir nosrc x nosrc_x unprofitable drnd lnage lndiffdate nasdaq90d lnnreg_filter i.famafrench if proceeds>=30 & proceeds<=120, robust cluster(ff_yr_qt)
eststo: xi: reg ir nosrc x nosrc_x unprofitable drnd lnage lndiffdate nasdaq90d lnnreg_filter i.famafrench if proceeds>=0 & proceeds<=150, robust cluster(ff_yr_qt)
esttab using rd_ir_preAct.csv, pr2 ar2 nonotes eqlabels("") nonumber noconstant replace depvars drop(_I*) star(* 0.10 ** 0.05 *** 0.01) label b(%9.3f)
******* Figure 2: McCrary Test of Proceeds
preserve
keep if proceeds>=0 & proceeds<=300
DCdensity proceeds, breakpoint(75) generate(Xj Yj r0 fhat se_fhat)
graph export McCrary_preAct.png, replace
restore
******* Figure 3: Regression Discontinuity around SRC Threshold
preserve
drop if ir>100
twoway (scatter ir proceeds, mcolor(gs10) msize(tiny)) ///
(lfit ir proceeds if proceeds<=75, lcolor(navy) lwidth(medthick)) ///
(lfit ir proceeds if proceeds>75, lcolor(maroon) lwidth(medthick)) ///
if proceeds>=50 & proceeds<=100, xline(75, lcolor(gs6) lpattern(dash)) legend(off) xtitle(Proceeds) ytitle(Initial Return (%)) yscale(range(-30,100)) ylabel(-20(20)100)
graph export rd_preAct.png, replace
restore
******* Table 6: JOBS Act Provisions
use FINAL_SAMPLE, clear
keep if egcipo==1
gen ttw_yes=1 if testwaters==1 & egcatipo==1
replace ttw_yes=0 if testwaters==0 & egcatipo==1
replace ttw_yes=0 if testwaters==-1 & egcatipo==1
gen ttw_no=1 if testwaters==0 & egcatipo==1
replace ttw_no=0 if testwaters==1 & egcatipo==1
replace ttw_no=0 if testwaters==-1 & egcatipo==1
gen ttw_yesmay=1 if testwaters==1 & egcatipo==1
replace ttw_yesmay=1 if testwaters==-1 & egcatipo==1
replace ttw_yesmay=0 if testwaters==0 & egcatipo==1
gen soxvoted_yes=0
replace soxvoted_yes=1 if sox_yes==1
replace soxvoted_yes=1 if voted_yes==1
gen soxvoted_no=0
replace soxvoted_no=1 if sox_no==1
replace soxvoted_no=1 if voted_no==1
gen soxvoted_yesmay=0
replace soxvoted_yesmay=1 if sox_yes==1
replace soxvoted_yesmay=1 if sox_may==1
replace soxvoted_yesmay=1 if voted_yes==1
replace soxvoted_yesmay=1 if voted_may==1
gen egcchoice_yes=confidential_yes+sox_yes+execcomp_yes+voted_yes+newrule_yes+financial_yes+ttw_yes
gen egcchoice_no=confidential_no+sox_no+execcomp_no+voted_no+newrule_no+financial_no+ttw_no
gen egcchoice_may=sox_may+execcomp_may+voted_may+newrule_may+financial_may
gen egcchoice_yesmay=confidential_yesmay+sox_yesmay+execcomp_yesmay+voted_yesmay+newrule_yesmay+financial_yesmay+ttw_yesmay
gen period=.
replace period=1 if idate>=date("4/5/2012","MDY",2012) & idate<date("4/4/2013","MDY",2012)
replace period=2 if idate>=date("4/5/2013","MDY",2012) & idate<date("4/4/2014","MDY",2012)
replace period=3 if idate>=date("4/5/2014","MDY",2012) & idate<date("4/30/2015","MDY",2012)
tab confidential if egcatipo==1
bys period: tab confidential if egcatipo==1
tab testwaters if egcatipo==1
bys period: tab testwaters if egcatipo==1
tab financial if egcatipo==1
bys period: tab financial if egcatipo==1
tab execcomp if egcatipo==1
bys period: tab execcomp if egcatipo==1
tab sox if egcatipo==1
bys period: tab sox if egcatipo==1
tab voted if egcatipo==1
bys period: tab voted if egcatipo==1
tab newrule if egcatipo==1
bys period: tab newrule if egcatipo==1
tabstat egcchoice_may if egcatipo==1
tabstat egcchoice_may if egcatipo==1, by(period)
tabstat egcchoice_no if egcatipo==1
tabstat egcchoice_no if egcatipo==1, by(period)
tabstat egcchoice_yes if egcatipo==1
tabstat egcchoice_yes if egcatipo==1, by(period)
******* Table 7: Determinants of Disclosure Choices
label var egcchoice_no "Number of 'No' Choices"
joinby sic using HIGHTECH, unmatched(master)
tab _merge
drop _merge
replace hightech=0 if missing(hightech)
drop famafrench
gen famafrench=1
replace famafrench=2 if hightech==1
replace famafrench=3 if dum_biopharma==1
est clear
eststo: xi: reg egcchoice_no lnproceeds_res unprofitable lnage booklev ppenet_asset rnd_asset avrg_brmktsh, robust
eststo: xi: reg egcchoice_no lnproceeds_res unprofitable lnage booklev ppenet_asset rnd_asset avrg_brmktsh i.period, robust
eststo: xi: reg egcchoice_no lnproceeds_res unprofitable lnage booklev ppenet_asset rnd_asset avrg_brmktsh i.famafrench, robust
eststo: xi: reg egcchoice_no lnproceeds_res unprofitable lnage booklev ppenet_asset rnd_asset avrg_brmktsh i.famafrench i.period, robust
esttab using disclosure.csv, pr2 ar2 notes eqlabels("") nonumber replace depvars star(* 0.10 ** 0.05 *** 0.01) label b(%9.3f)
******* Figure 1 & Table 1: Sample of IPOs
use FINAL_SAMPLE, clear
drop mo qt
gen mo=month(idate)
gen qt=1 if mo==1|mo==2|mo==3
replace qt=2 if mo==4|mo==5|mo==6
replace qt=3 if mo==7|mo==8|mo==9
replace qt=4 if mo==10|mo==11|mo==12
gen ipo=1
gen control=(egcbyrev==0)
gen egcc=(egcbyrev==1)
gen nonq=(missing(egcbyrev))
gen nonsrc=(src==0)
collapse (sum) ipo control egcc nonq src nonsrc, by(yr qt)
browse
******* Figure 4: Residual IR
use FINAL_SAMPLE, clear
keep if !missing(egcbyrev)
xi: reg ir dp lnproceeds_res unprofitable lnage avrg_uwmktsh diffdate nasdaq90d nreg_filter crisis i.famafrench, robust cluster(ff_yr_qt)
predict ir_res, res
drop mo qt
gen mo=month(idate)
gen qt=1 if mo==1|mo==2|mo==3
replace qt=2 if mo==4|mo==5|mo==6
replace qt=3 if mo==7|mo==8|mo==9
replace qt=4 if mo==10|mo==11|mo==12
collapse (count) nipos=ir (mean) ir_res, by(yr)
browse
***Analysis for "Investor Behavior and the Benefits of Direct Stock Ownership"***
*Darren Bernard, Nicole Cade, and Frank Hodge
*Last updated with annotations December 2017
*Bring in data
use ""
*See dataset available on JAR website
set more off
****Clean up variables
*SingleName variable from survey instrument indicates absence of any direct stock ownership
replace NumberInvestments = 0 if SingleName == 0
*Missing for ShareCr (for sharing a credit card) actually indicates no shared credit card data
replace ShareCr = 0 if missing(ShareCr) & Finished == 1
*Reset OwnMoney DV to zero if participant never pays for anything at Starbucks
replace OwnMoney = 0 if Pay_Never == 100
*Reset OwnMoney_Alt (an alternative construction) DV to zero if participant never pays for anything at Starbucks
replace OwnMoney_Alt = 0 if Pay_Never == 100
*Reset NumVisits DV to zero if participant never pays for anything at Starbucks
replace NumVisits = 0 if Pay_Never == 100
*Sum cash payment and gift card proportions
gen Cash_GC_Pays = Pay_Cash + Pay_GiftCard
*Set OwnMoney, OwnMoney_Alt, and NumVisits to be missing when missing a lot of (untrackable) purchase data
replace OwnMoney = . if Cash_GC_Pays > 50 & !missing(Pay_Cash) & !missing(Pay_GiftCard)
replace OwnMoney_Alt = . if Cash_GC_Pays > 50 & !missing(Pay_Cash) & !missing(Pay_GiftCard)
replace NumVisits = . if Cash_GC_Pays > 50 & !missing(Pay_Cash) & !missing(Pay_GiftCard)
*Reset SelfReported to be zero if participant did not self report either CC purchases or App
replace SelfReported = 0 if SelfReported == .5
*Reset Include condition for a couple observations with invalid data
replace Include = 0 if missing(SingleName)
*Do continuous variable standardization
foreach var in OwnMoney OwnMoney_Alt NumVisits RegulatoryAlignment Influence_Purchasing Influence_Voting Affect Dissonance_Purchasing Dissonance_Voting Income Age NumberInvestments CoffeeTeaDrinks WorkGroupTime SBUXLinks FreqComments ToneComments NumberMeetings ReportingConfidence EarningsBeatLikelihood PerceivedConsistency Conservative Access {
forvalues x = 1(1)3 {
egen z_`var'`x' = std(`var') if University == `x' & Include == 1
replace z_`var'`x' = 0 if missing(z_`var'`x')
}
gen z_`var' = z_`var'1 + z_`var'2 + z_`var'3
replace z_`var' = . if missing(`var')
drop z_`var'1 z_`var'2 z_`var'3
}
*Generate treatment interactions for potential moderators
foreach var in z_Income Female z_Age USNational z_NumberInvestments z_CoffeeTeaDrinks {
gen T_`var' = Treatment*`var'
}
*Generate treatment interactions for mediation
foreach var in z_Influence_Purchasing z_Influence_Voting {
gen T_`var' = Treatment*`var'
}
*Generate treatment interactions for social connections
foreach var in z_WorkGroupTime z_SBUXLinks {
gen T_`var' = Treatment*`var'
}
***************************************************************
***CODE FOR MAIN TABLES***
***TABLE 1: Descriptive statistics***
matrix descriptives = J(29,5,0)
local n = 0
foreach var in OwnMoney OthersMoney RegulatoryAlignment Influence_Purchasing Influence_Voting Affect Dissonance_Purchasing Dissonance_Voting Income Female Age USNational NumberInvestments CoffeeTeaDrinks WorkGroupTime SBUXLinks NumberMeetings FreqComments ToneComments ReportingConfidence PerceivedConsistency EarningsBeatLikelihood SelfReported ShareCr Conservative Coffee_YN Access {
local n = `n' + 1
qui su `var' if Include == 1, detail
matrix descriptives[`n',1] = `r(p25)'
matrix descriptives[`n',2] = `r(p50)'
matrix descriptives[`n',3] = `r(p75)'
matrix descriptives[`n',4] = `r(mean)'
matrix descriptives[`n',5] = `r(N)'
}
matrix list descriptives
***TABLE 2: Comparisons across experimental conditions of OwnMoney, OthersMoney, and Regulatory Alignment***
*Panel A: OwnMoney
ttest z_OwnMoney if Include == 1, by(Treatment)
*Panel B: OthersMoney
tabulate OthersMoney Treatment if Include == 1, chi2
su OthersMoney if Treatment == 1 & Include == 1
su OthersMoney if Treatment == 0 & Include == 1
*Panel C: RegulatoryAlignment
ttest z_RegulatoryAlignment if Include == 1, by(Treatment)
***TABLE 3 ORIGINAL: Mediation analyses for OwnMoney, OthersMoney, and RegulatoryAlignment***
*Panel A: OwnMoney
reg z_OwnMoney Treatment T_z_Influence_Purchasing z_Affect z_Dissonance_Purchasing if Include == 1
*Panel B: OthersMoney
logit OthersMoney Treatment T_z_Influence_Purchasing z_Affect z_Dissonance_Purchasing if Include == 1
*Panel C: RegulatoryAlignment
reg z_RegulatoryAlignment Treatment T_z_Influence_Voting z_Affect z_Dissonance_Voting if Include == 1
***TABLE 3 ALTERNATIVE (DUE TO NULL RESULTS): Comparisons across experimental conditions of mediation variables***
corr z_OwnMoney z_Influence_Purchasing if Include == 1 & Treatment == 1
pwcorr z_OwnMoney z_Influence_Purchasing if Include == 1 & Treatment == 1, sig
corr z_OwnMoney z_Influence_Purchasing if Include == 1 & Treatment == 0
pwcorr z_OwnMoney z_Influence_Purchasing if Include == 1 & Treatment == 0, sig
reg z_OwnMoney Treatment z_Influence_Purchasing T_z_Influence_Purchasing if Include == 1
/*
*Check results using "cortesti" command
cortesti 0.0999 106 -0.0672 115
*/
corr OthersMoney z_Influence_Purchasing if Include == 1 & Treatment == 1
pwcorr OthersMoney z_Influence_Purchasing if Include == 1 & Treatment == 1, sig
corr OthersMoney z_Influence_Purchasing if Include == 1 & Treatment == 0
pwcorr OthersMoney z_Influence_Purchasing if Include == 1 & Treatment == 0, sig
reg OthersMoney Treatment z_Influence_Purchasing T_z_Influence_Purchasing if Include == 1
corr z_RegulatoryAlignment z_Influence_Voting if Include == 1 & Treatment == 1
pwcorr z_RegulatoryAlignment z_Influence_Voting if Include == 1 & Treatment == 1, sig
corr z_RegulatoryAlignment z_Influence_Voting if Include == 1 & Treatment == 0
pwcorr z_RegulatoryAlignment z_Influence_Voting if Include == 1 & Treatment == 0, sig
reg z_RegulatoryAlignment Treatment z_Influence_Voting T_z_Influence_Voting if Include == 1
ttest z_Affect if Include == 1, by(Treatment)
ttest z_Dissonance_Purchasing if Include == 1, by(Treatment)
ttest z_Dissonance_Voting if Include == 1, by(Treatment)
***TABLE 4: Individual characteristics as potential moderators***
*Panel A: OwnMoney
reg z_OwnMoney Treatment z_Income T_z_Income if Include == 1
outreg2 using table4_reg, stats(coef tstat) bdec(3) tdec(2) excel ctitle(1) replace
reg z_OwnMoney Treatment Female T_Female if Include == 1
outreg2 using table4_reg, stats(coef tstat) bdec(3) tdec(2) excel ctitle(2)
reg z_OwnMoney Treatment z_Age T_z_Age if Include == 1
outreg2 using table4_reg, stats(coef tstat) bdec(3) tdec(2) excel ctitle(3)
reg z_OwnMoney Treatment USNational T_USNational if Include == 1
outreg2 using table4_reg, stats(coef tstat) bdec(3) tdec(2) excel ctitle(4)
reg z_OwnMoney Treatment z_NumberInvestments T_z_NumberInvestments if Include == 1
outreg2 using table4_reg, stats(coef tstat) bdec(3) tdec(2) excel ctitle(5)
reg z_OwnMoney Treatment z_CoffeeTeaDrinks T_z_CoffeeTeaDrinks if Include == 1
outreg2 using table4_reg, stats(coef tstat) bdec(3) tdec(2) excel ctitle(6)
reg z_OwnMoney Treatment z_Income Female z_Age USNational z_NumberInvestments z_CoffeeTeaDrinks T_z_Income T_Female T_z_Age T_USNational T_z_NumberInvestments T_z_CoffeeTeaDrinks if Include == 1
outreg2 using table4_reg, stats(coef tstat) bdec(3) tdec(2) excel ctitle(7)
*Panel B: OthersMoney
logit OthersMoney Treatment z_Income T_z_Income if Include == 1
outreg2 using table4_reg, stats(coef tstat) bdec(3) tdec(2) excel ctitle(1) replace
logit OthersMoney Treatment Female T_Female if Include == 1
outreg2 using table4_reg, stats(coef tstat) bdec(3) tdec(2) excel ctitle(2)
logit OthersMoney Treatment z_Age T_z_Age if Include == 1
outreg2 using table4_reg, stats(coef tstat) bdec(3) tdec(2) excel ctitle(3)
logit OthersMoney Treatment USNational T_USNational if Include == 1
outreg2 using table4_reg, stats(coef tstat) bdec(3) tdec(2) excel ctitle(4)
logit OthersMoney Treatment z_NumberInvestments T_z_NumberInvestments if Include == 1
outreg2 using table4_reg, stats(coef tstat) bdec(3) tdec(2) excel ctitle(5)
logit OthersMoney Treatment z_CoffeeTeaDrinks T_z_CoffeeTeaDrinks if Include == 1
outreg2 using table4_reg, stats(coef tstat) bdec(3) tdec(2) excel ctitle(6)
logit OthersMoney Treatment z_Income Female z_Age USNational z_NumberInvestments z_CoffeeTeaDrinks T_z_Income T_Female T_z_Age T_USNational T_z_NumberInvestments T_z_CoffeeTeaDrinks if Include == 1
outreg2 using table4_reg, stats(coef tstat) bdec(3) tdec(2) excel ctitle(7)
*Panel C: RegulatoryAlignment
reg z_RegulatoryAlignment Treatment z_Income T_z_Income if Include == 1
outreg2 using table4_reg, stats(coef tstat) bdec(3) tdec(2) excel ctitle(1) replace
reg z_RegulatoryAlignment Treatment Female T_Female if Include == 1
outreg2 using table4_reg, stats(coef tstat) bdec(3) tdec(2) excel ctitle(2)
reg z_RegulatoryAlignment Treatment z_Age T_z_Age if Include == 1
outreg2 using table4_reg, stats(coef tstat) bdec(3) tdec(2) excel ctitle(3)
reg z_RegulatoryAlignment Treatment USNational T_USNational if Include == 1
outreg2 using table4_reg, stats(coef tstat) bdec(3) tdec(2) excel ctitle(4)
reg z_RegulatoryAlignment Treatment z_NumberInvestments T_z_NumberInvestments if Include == 1
outreg2 using table4_reg, stats(coef tstat) bdec(3) tdec(2) excel ctitle(5)
reg z_RegulatoryAlignment Treatment z_CoffeeTeaDrinks T_z_CoffeeTeaDrinks if Include == 1
outreg2 using table4_reg, stats(coef tstat) bdec(3) tdec(2) excel ctitle(6)
reg z_RegulatoryAlignment Treatment z_Income Female z_Age USNational z_NumberInvestments z_CoffeeTeaDrinks T_z_Income T_Female T_z_Age T_USNational T_z_NumberInvestments T_z_CoffeeTeaDrinks if Include == 1
outreg2 using table4_reg, stats(coef tstat) bdec(3) tdec(2) excel ctitle(7)
***TABLE 5: The effects of social connections***
*Panel A: Field Measures of Social Connections
reg z_OwnMoney Treatment z_WorkGroupTime T_z_WorkGroupTime if Include == 1
outreg2 using table5_reg, stats(coef tstat) bdec(3) tdec(2) excel ctitle(1) replace
reg z_OwnMoney Treatment z_SBUXLinks T_z_SBUXLinks if Include == 1
outreg2 using table5_reg, stats(coef tstat) bdec(3) tdec(2) excel ctitle(2)
logit OthersMoney Treatment z_WorkGroupTime T_z_WorkGroupTime if Include == 1
outreg2 using table5_reg, stats(coef tstat) bdec(3) tdec(2) excel ctitle(3)
logit OthersMoney Treatment z_SBUXLinks T_z_SBUXLinks if Include == 1
outreg2 using table5_reg, stats(coef tstat) bdec(3) tdec(2) excel ctitle(4)
reg z_RegulatoryAlignment Treatment z_WorkGroupTime T_z_WorkGroupTime if Include == 1
outreg2 using table5_reg, stats(coef tstat) bdec(3) tdec(2) excel ctitle(5)
reg z_RegulatoryAlignment Treatment z_SBUXLinks T_z_SBUXLinks if Include == 1
outreg2 using table5_reg, stats(coef tstat) bdec(3) tdec(2) excel ctitle(6)
*Panel B: Self-Reported Measures of Social Connections
ttest z_NumberMeetings if Include == 1, by(Treatment)
ttest z_FreqComments if Include == 1, by(Treatment)
ttest z_ToneComments if Include == 1, by(Treatment)
***TABLE 6: Other investor preferences and perceptions***
ttest z_ReportingConfidence if Include == 1, by(Treatment)
ttest z_PerceivedConsistency if Include == 1, by(Treatment)
ttest z_EarningsBeatLikelihood if Include == 1, by(Treatment)
***TABLE 7: Bayesian analysis***
set seed 14
bayesmh OwnMoney Treatment if Include == 1, likelihood(normal({var})) prior({OwnMoney: _cons}, flat) prior ({OwnMoney: Treatment}, normal(0,10)) prior({var}, jeffreys)
bayesgraph diagnostics _all
set seed 14
bayesmh OwnMoney Treatment if Include == 1, likelihood(normal({var})) prior({OwnMoney: _cons}, flat) prior ({OwnMoney: Treatment}, normal(0,100)) prior({var}, jeffreys)
bayesgraph diagnostics _all
set seed 14
bayesmh OwnMoney Treatment if Include == 1, likelihood(normal({var})) prior({OwnMoney: _cons}, flat) prior ({OwnMoney: Treatment}, normal(40,10)) prior({var}, jeffreys)
bayesgraph diagnostics _all
set seed 14
bayesmh OwnMoney Treatment if Include == 1, likelihood(normal({var})) prior({OwnMoney: _cons}, flat) prior ({OwnMoney: Treatment}, normal(40,100)) prior({var}, jeffreys)
bayesgraph diagnostics _all
set seed 14
bayesmh OthersMoney Treatment if Include == 1, likelihood(logit) prior({OthersMoney: _cons}, flat) prior ({OthersMoney: Treatment}, normal(0,0.01))
bayesgraph diagnostics _all
set seed 14
bayesmh OthersMoney Treatment if Include == 1, likelihood(logit) prior({OthersMoney: _cons}, flat) prior ({OthersMoney: Treatment}, normal(0,0.1))
bayesgraph diagnostics _all
set seed 14
bayesmh OthersMoney Treatment if Include == 1, likelihood(logit) prior({OthersMoney: _cons}, flat) prior ({OthersMoney: Treatment}, normal(0.2,0.01))
bayesgraph diagnostics _all
set seed 14
bayesmh OthersMoney Treatment if Include == 1, likelihood(logit) prior({OthersMoney: _cons}, flat) prior ({OthersMoney: Treatment}, normal(0.2,0.1))
bayesgraph diagnostics _all
set seed 14
bayesmh RegulatoryAlignment Treatment if Include == 1, likelihood(normal({var})) prior({RegulatoryAlignment: _cons}, flat) prior ({RegulatoryAlignment: Treatment}, normal(0,10)) prior({var}, jeffreys)
bayesgraph diagnostics _all
set seed 14
bayesmh RegulatoryAlignment Treatment if Include == 1, likelihood(normal({var})) prior({RegulatoryAlignment: _cons}, flat) prior ({RegulatoryAlignment: Treatment}, normal(0,100)) prior({var}, jeffreys)
bayesgraph diagnostics _all
set seed 14
bayesmh RegulatoryAlignment Treatment if Include == 1, likelihood(normal({var})) prior({RegulatoryAlignment: _cons}, flat) prior ({RegulatoryAlignment: Treatment}, normal(20,10)) prior({var}, jeffreys)
bayesgraph diagnostics _all
set seed 14
bayesmh RegulatoryAlignment Treatment if Include == 1, likelihood(normal({var})) prior({RegulatoryAlignment: _cons}, flat) prior ({RegulatoryAlignment: Treatment}, normal(20,100)) prior({var}, jeffreys)
bayesgraph diagnostics _all
import excel "all_base.xls", sheet("Full") firstrow
save base, replace
clear all
import excel "all_same.xls", sheet("Full") firstrow
save same, replace
clear all
import excel "all_sep.xls", sheet("Full") firstrow
save sep, replace
append using base, force
append using same
save all, replace
use all, clear
drop Auditor4TimesAccurateLag Auditor4TimesHiredLag Auditor4TimesInspectedLag Auditor4TimesPenaltyLag Bid5
drop if Period <6
drop if Period >20
gen cond =0
replace cond=1 if Condition == "Sep"
replace cond =2 if Condition =="Same"
bysort Session: egen ave_aq = mean(VerifierInvestigation)
bysort Session: egen ave_mi = mean(MgrInvestment)
gen c1a=0
replace c1a =-1 if cond==2
replace c1a =1 if cond==0
gen c2a=-1
replace c2a=2 if cond==1
gen MgrID = Session*100 + AssetNumber
gen AuditorID = Session*100 + AuditorHired
gen BuyerID = Session*100 + HighBidder
gen ConsultantID = Session*100 + ConsultantHired
gen base=0
replace base=1 if Condition == "Base"
gen same=0
replace same=1 if Condition =="Same"
gen sep=0
replace sep=1 if Condition =="Sep"
gen AuditorAccuracyPer = .
replace AuditorAccuracyPer = Auditor1TimesAccurateLag / Auditor1TimesHiredLag if AuditorHired == 1
replace AuditorAccuracyPer = Auditor2TimesAccurateLag / Auditor2TimesHiredLag if AuditorHired == 2
replace AuditorAccuracyPer = Auditor3TimesAccurateLag / Auditor3TimesHiredLag if AuditorHired == 3
gen repval =200
replace repval=400 if ReportedValue==1
replace repval=600 if ReportedValue==2
replace repval=800 if ReportedValue==3
replace repval=1000 if ReportedValue==4
replace repval=1200 if ReportedValue==5
gen Confidence = HighBid - repval
gen repval_center_0_800 = repval - 800
summarize repval, meanonly
gen centered_repval = repval - r(mean)
summarize AuditorAccuracyPer, meanonly
gen centered_AudAccPer = AuditorAccuracyPer - r(mean)
summarize Period, meanonly
gen centered_Period = Period - r(mean)
save all_2, replace
*Table 1
mean VerifierInvestigation MgrInvestment MgrMisreport HighBid HighBidderEarned, over(Session)
mean ConsultantEffort, over(Session)
*Linked session to condition and organized columns by our audit quality measure (VerifierInvestigation) in excel.
*Table 2 - Panel A
duplicates drop Session, force
by cond, sort : summarize ave_aq
use all_2, clear
*Table 2 - Panel C
melogit VerifierInvestigation c1a c2a || Session: || AuditorID:
melogit VerifierInvestigation base same || Session: || AuditorID:
*Table 2 - Panel B
*From above Logit, Chi-2(2) = .88; .88/2 DFs = .44. P-value = .65
*Table 5 - Column 1
melogit MgrInvestment AuditorAccuracyPer || Session: || MgrID:
*Drop observations with maximum value assets as there is no potential to misreport
drop if TrueValue ==5
*Table 5 - Column 2
melogit MgrMisreport AuditorAccuracyPer || Session: || MgrID:
use all_2, clear
*Table 7 - Column 1
mixed Confidence c.centered_AudAccPer##c.repval_center_0_800 centered_Period || Session: || BuyerID: if repval !=200 & AuditorReport != 0
*Table 7 - Column 2
mixed Confidence c.centered_AudAccPer##c.repval_center_0_800 centered_Period sep same || Session: || BuyerID: if repval !=200 & AuditorReport != 0
use all, clear
gen MgrID = Session*100 + AssetNumber
gen AuditorID = Session*100 + AuditorHired
gen BuyerID = Session*100 + HighBidder
gen ConsultantID = Session*100 + ConsultantHired
*Set up Table 3
gen one = 1
sort AuditorID
by AuditorID: gen Count = sum(one)
bysort AuditorID: egen aa = max(Count)
by AuditorID: gen Aud_AQ_Count = sum(VerifierInvestigation)
bysort AuditorID: egen bb = max(Aud_AQ_Count)
gen Aud_AQ = bb / aa
sort ConsultantID Period
by ConsultantID: gen Cons_Count = sum(one)
bysort ConsultantID: egen cc = max(Cons_Count)
by ConsultantID: gen Cons_HE_Count = sum(ConsultantEffort)
bysort ConsultantID: egen dd = max(Cons_HE_Count)
gen Cons_Effort = dd / cc
bysort Session: gen decisions = sum(one)
bysort Session: egen max_hires = max(decisions)
bysort AuditorID: gen mktshr = aa/max_hires
bysort ConsultantID: gen c_mktshr = cc/max_hires
save temp1, replace
use temp1, clear
duplicates drop AuditorID, force
keep Session Condition AuditorID Aud_AQ mktshr
gsort Session -Aud_AQ
by Session: gen rank = _n
gsort Condition Session -aa
br
*Provides data for Table 3.
use temp1, clear
duplicates drop ConsultantID, force
drop if missing(ConsultantID)
keep Session Condition ConsultantID Cons_Effort c_mktshr
gsort Session -Cons_Effort
by Session: gen rank = _n
gsort Condition Session -aa
br
*Provides data for Table 3.
*Combine auditor and consultant information in excel.
*Note - Auditor 1 = Consultant 1, A2 = C2, and A3 = C3 in each session.
use all_2, clear
gen same_pref_hq_aud = 0
replace same_pref_hq_aud = 1 if Session == 9 | Session == 18 | Session == 1 | Session == 17
gen same_pref_lq_aud = 0
replace same_pref_lq_aud = 1 if Session == 5 | Session == 23 | Session == 11 | Session == 6
gen sep_pref_hq_aud = 0
replace sep_pref_hq_aud = 1 if Session == 19 | Session == 20 | Session == 3 | Session == 16
gen sep_pref_lq_aud = 0
replace sep_pref_lq_aud = 1 if Session == 22 | Session == 7 | Session == 14 | Session == 2
gen nas_pref_hq_aud = 0
replace nas_pref_hq_aud = 1 if same_pref_hq_aud == 1 | sep_pref_hq_aud == 1
gen nas_non_hq_aud = 0
replace nas_non_hq_aud = 1 if base == 0 & nas_pref_hq_aud == 0
gen hq_cond = ""
replace hq_cond = "Base" if base
replace hq_cond = "NAS HQ" if nas_pref_hq_aud
replace hq_cond = "NAS Non-HQ" if nas_non_hq_aud
*Table 4 - Panel B
melogit VerifierInvestigation nas_pref_hq_aud nas_non_hq_aud || Session: || AuditorID:
*Table 6 - Panel B
melogit MgrInvestment nas_pref_hq_aud || Session: || MgrID:
*Table 4 - Panel A
duplicates drop Session, force
by hq_cond, sort : summarize ave_aq
*Table 6 - Panel A
by hq_cond, sort : summarize ave_mi
Related skills
FAQ
Where do the patterns come from?
They are sourced from 126 Stata .do files in the Journal of Accounting Research Online Supplements, volumes 55-63.
Does it give research-design advice?
No. It provides Stata syntax from published papers but not identification strategy or methodological trade-off analysis.