Match by firm, year, industry, state, and size

1. Matching process, match year by year

use epa_b4_match.dta,clear
//Define treat: a firm ever experienced a closure in any of plants; add treat of hq in the original sample
//Remove hq state if the state has no treat
replace c_year=. if c_year==0
bys hq: egen t_close=count(treat)
drop if t_close==0
drop t_close
//Generate firm-year treat
bys gvkey year: egen total_c=sum(treat)
replace treat=1 if total_c>0
tab treat
drop total_c 
//Generate closure year for all treat
bys gvkey year:replace c_year=c_year[_n-1] if c_year==. & c_year[_n-1]!=. & treat==1
forv i=1(1)10{
bys gvkey year:replace c_year=c_year[_n+`i'] if c_year==. & c_year[_n+`i']!=. & treat==1
}
count if c_year==.& treat==1
drop if c_year==.& treat==1
duplicates drop gvkey year,force
tab treat
//Note: state is the headquarter state. Not EPA location state
egen state_d=group(hq)
destring sic,replace
//Size
bys year: egen sd_size_t=sd(market_v) if treat==1
bys year: egen l_size_t=max(market_v) if treat==1
bys year: egen s_size_t=min(market_v) if treat==1
gen size_max=2*l_size
gen size_min=0.5*s_size
drop sd_size_t l_size_t s_size_t
forvalues j = 1998(1)2020{
preserve
keep if year==`j'
//keep all control that matches year & sic.
gen pvalue=state_d*10000+sic*10
format %12.0g pvalue
sort pvalue
gen c=0 if treat==1
drop if treat==1 & treat[_n-1]==0 & abs(pvalue-pvalue[_n-1])>50  & treat[_n+1]==0 & abs(pvalue-pvalue[_n+1])>50

//size constraints
drop if size<s_size & treat!=1
drop if size>l_size & treat!=1

forv i=1(1)50{
qui replace c=1 if treat[_n+`i']==1 & treat==0 & abs(pvalue-pvalue[_n+`i'])<100
qui replace c_year=c_year[_n+`i'] if c_year==. & treat[_n+`i']==1 & treat==0 & abs(pvalue-pvalue[_n+`i'])<100
qui replace c=1 if c==. & treat[_n-`i']==1 & treat[_n+`i']==0& treat==0 & abs(pvalue-pvalue[_n-`i'])<100
qui replace c_year=c_year[_n-`i'] if c_year==. & treat[_n-`i']==1 & treat==0 & abs(pvalue-pvalue[_n-`i'])<100
}
egen sum_c=sum(c)
drop if sum_c==0
drop if missing(c_year)
drop c sum_c
save year`j'.dta,replace
restore
}

use year1998.dta,clear
forvalues i = 1999(1)2020{
cap append using year`i'.dta
//erase year`i'.dta
} 
tab year treat
count if missing(c_year)
gen post=1 if year>(c_year-1)
replace post=0 if post==.
gen treat_x_post=treat*post
rename ana_cov2 n_analysts
//Drop single observations
bys gvkey county sic:gen year_obs=_N
drop if year_obs==1
drop year_obs
global yy  "size m_cap lev roa n_analysts ins_hold ave_vol ret_sd mtb sd_roa fund_cor raw_ta mean_ret ind_HHI ind_size ind_size_raw"
foreach x in $yy{
drop if missing(`x')
}
winsor2 raw_ta sd_roa mtb,replace cuts(1 99)
bys gvkey county sic:gen year_obs=_N
drop if year_obs==1
drop year_obs
save ...dta,replace

2. Revise: match the control firm years to the corresponding treatment firm years.

//1) Generate group number
use year_by_size.dta,clear
keep if treat==1
duplicates drop gvkey,force
keep gvkey treat
gen group=_n 
save treat_group.dta,replace

//2) generate treated and control group matches
use year_by_size.dta,clear
merge m:1 treat gvkey using treat_group,nogen
replace group=0 if group==.
forvalues j = 1998(1)2020{
preserve
keep if year==`j'
gsort state pvalue 
forv i=1(1)50{
qui replace group=group[_n-`i'] if group[_n-`i']>0 &treat[_n-`i']==1 & treat==0 /// 
	& pvalue - pvalue[_n-`i']< 200 & state==state[_n-`i'] &group==0
}
qui replace group=group[_n-1] if gvkey==gvkey[_n-1] &group==0
qui replace group=group[_n-1] if pvalue==pvalue[_n-1] &group==0
forv i=1(1)50{
qui replace group=group[_n+`i'] if group[_n+`i']>0 &treat[_n+`i']==1 & treat==0 /// 
	& pvalue[_n+`i']- pvalue < 200 & state==state[_n+`i'] &group==0
}
save year`j'.dta,replace
restore
}

use year1998.dta,clear
forvalues i = 1999(1)2020{
cap append using year`i'.dta
} 
count if group==0
forv i=1(1)10{
qui replace group=group[_n-`i'] if group[_n-`i']>0 & treat==0 &group==0
}
count if group==0
save year_by_size_group.dta,replace
erase treat_group.dta

3. Parallel assumption graph using matched groups.

//3) With groups, we can do parallel assumtion. Graph approach
use year_by_size_group.dta,clear
bys group: egen event=min(year) if treat==1 &post==1
bys group: egen e_year=min(event)
bys group: gen time=year-e_year
//bro group treat post year event if time==.
drop event e_year
bys group: egen event=min(year) if treat==0 &post==1&missing(time)
bys group: egen e_year=min(event)
bys group: replace time=year-e_year if missing(time)
drop if time==.
//drop if time<-3
replace time=-3 if time<-3
tab time
bysort time: egen control = mean(sync) if treat == 0
bysort time: egen treated = mean(sync) if treat == 1
twoway line control treated time, xline(0, lwidth(thin) lcolor(green)) ytitle("Average synchronicity") xtitle("years relevant to the closure year") 
graph save "Parallel_trend.gph",replace  

4. Cross-sectional tests using the created groups. Media coverage as an example.


use year_by_size_group.dta,clear
drop if year<2000
merge 1:m gvkey year using  rp_media_annual.dta
///2061 obs from master data are not merged, 6437 merged
//rp_media_annual.dta: only annual article count
keep if _merge==3
drop _merge
//Partition by pre-closure level of coverage. Post=0 treat=1
sum media_cov if treat==1 &post==0,de 
//find the median=357,only partition on treated group
gen low_cov=1 if media_cov<5.905 & treat==1
bys group: egen sum_media=sum(low_cov)
replace low_cov=1 if sum_media>0
replace low_cov=0 if low_cov==.
tab low_cov
drop sum_media

global yy  " treat_x_post post size lev roa mtb n_analysts ins_hold ave_vol mean_ret ret_sd fund_cor  sd_roa raw_ta ind_size ind_HH "
foreach x in $yy{
gen me_`x'=`x'*low_cov
}
global zz "low_cov me_treat_x_post me_post me_size me_lev me_roa me_mtb me_n_analysts me_ins_hold me_ave_vol me_mean_ret me_ret_sd me_fund_cor me_sd_roa me_raw_ta me_ind_size me_ind_HH"

reghdfe sync  $yy $zz , absorb(gvkey year) cluster(gvkey)
global aa "treat_x_post post low_cov me_treat_x_post"
outreg2 using cs_int_all.doc , append tstat addtext( Firm FE, YES, Year FE, YES) ctitle(low_cov_post) keep($aa) dec(3)

asdoc test me_treat_x_post==0, replace save(F-test) 

reghdfe sync $yy if low_cov==1,absorb(year gvkey) cluster(gvkey)
outreg2 using CS_media_cov.doc , replace tstat addtext( Firm FE, YES, Year FE, YES) ctitle(Dummy=1) title(low_cov_pre) drop(i.year i.sic ) dec(3)
reghdfe sync $yy if low_cov==0,absorb(year gvkey) cluster(gvkey)
outreg2 using CS_media_cov.doc , append tstat addtext( Firm FE, YES, Year FE, YES) ctitle(Dummy=0) title(low_cov_pre) drop(i.year i.sic ) dec(3)
bys treat:asdoc sum media_cov if post==0, stat(N mean median min max) save(cs_descript) replace dec(3) title(Media_cov_pre)
bys treat:asdoc sum media_cov if post==1, stat(N mean median min max) save(cs_descript) append dec(3) title(Media_cov_post)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值