This analysis is suggested by discussant Samuel Antill in 2025 AFA meeting.
S1. Download and Load the Raw Dataset
We download the firm-level capital structure = from Compustat-CapitalIQ North America. The first measure of executory contracts is accounting data which (under U.S. GAAP) cover leases and rental contracts. We use the variables “Debt Equivalent of Operating Leases”, “Capital Leases” and “Net Rental Expenses”.
Debt - Capitalized Lease Obligations (dclo): This item represents long-term obligations due in respect of lease finances and hire purchase arrangements. This item includes:
Long-term finance lease obligations
Long-term lease financing
Long-term hire purchase obligations
Non-current obligations under capital leases
Rental Expense (xrent): This item represents all costs charged to operations for rental, lease, or hire of space and/or equipment. This item includes:
Airlines’ landing fees
Contingent rentals associated with capitalized leases
Lease charges and plant hire
This xrent variable is used in Section 5.1. In the main test, we construct a new variable called total rent, which is defined as the total rental commitment mrc1 + mrc2 + mrc3 + mrc4 + mrc5 + mrct reported in year t.
Asset - Total (at): Book value of total assets.
Debt in Current Liabilities - Total (dlc) is for the short-term debt and Long-term debt - Total (dltt) is for the long-term debt.
Earnings Before Interest (EBITDA): EBITDA.
Industry classifications: naics, sic and spcindcd + (Fama-French 30 Industry Classifiers, To Be Added / Definition).
We download all annual observations with Data Date (datadate) between Jan 2000 and Dec 2007 and restrict to firms either incorporated or having headquarters in US (i.e. fic == "USA" | loc == "USA"). Given that the policy shock happens under the US jurisdiction, we expect more significant treatment effect to be detected in this sample. The period used in Samuel’s slides is between 2002 and 2007, which is after the doc.com bubble and after the GFC. The variables in the dataset are:
Show the code
## load the compustat_na data # compustat_na <- as_tibble(read.csv(file = "C:/Users/13613/OneDrive - Handelshögskolan i Stockholm/Projects_2024/BeckerJosephsonXu_2025/AFA_meeting_response/Data/g4f68dkn3beu1iag.csv") )compustat_na <-as_tibble(read.csv(file ="C:/Users/13613/OneDrive - Handelshögskolan i Stockholm/Projects_2024/BeckerJosephsonXu_2025/AFA_meeting_response/Data/azsyeo1yjmrb2q1v.csv") ) %>%filter(fic =="USA"| loc =="USA" ) ## keep only US related observations (| fic == "CAN" | loc == "CAN")## data file record: # | Feb 24, 2025 > azsyeo1yjmrb2q1v.csv # | Jan 14, 2025 > g4f68dkn3beu1iag.csv ## check the variable names cat("Variables include:\n\n")sort(names(compustat_na))
Two dependent variables are constructed to measure firm’s leverage: (cf. p18 and Table 2 of the paper)
Book leverage: we define leverage as the ratio of the sum of short-term debt and long-term debt to assets (we drop observations where this is outside the [0,1] range)*.
Debt/EBITDA: we define debt-to-EBITDA as the ratio of the long- and short-term debt to EBITDA (we drop observations where this is outside the [0,15] range)*.
*These restrictions are imposed only in analyses in Section 5.2.
Note 1
What should be the best way to construct this PV of Rent / Net Rental Expenses variable in this test?
Show the code
## set the base year base_year <-2005## create leverage variables data <- compustat_na %>%# filter(at > 0) %>% filter(indfmt =="INDL") %>%## remove all financial firmsmutate(## leverage variables: book_leverage = (dlc + dltt) / at, debt_ebitda = (dlc + dltt) / ebitda, ## treatment intensity: totalrent = mrc1 + mrc2 + mrc3 + mrc4 + mrc5 + mrct, # total rent w/o discount# contract_intensity = (dclo + xrent * 3) / at, # executory contract intensitycontract_intensity = (dclo + totalrent) / at, # executory contract intensity# contract_intensity = (totalrent) / at, # executory contract intensity## other variables: dyear =as.integer(substr(datadate, start =1, stop =4)) # data year ) ## record the variable names cat("Variables include:\n\n")sort(names(data))
The main independent variable in the test is executory contract intensity, which is named as contract_intensity in our dataset. We follow Samuel’s definition w/o purchase contracts information for firm i at year t:
Then, we construct the dataset for the difference-in-difference analysis.
In this section, we use all observations without missing values in subsequent analyses.
The original dataset (data) contains observations with data year (dyear) range in [1997, 2009] and we restrict the sample to the data year in [2002, 2007].
For results with restrictions on specific variables, please refer to Section 5.2.
Note 2
Does altering the time (i.e. 2000 to 1995) for measuring the treatment intensity alter the results?
s3.1. try-and-error with calender year dyear
In this section, we first try to use the year information dyear extracted from variable datadate as the periods.
On top of the base data, we add several new variables in dataset data_did:
contract_intensity_2000: the contract intensity for each firm in year dyear == 2000.
post_2005: an indicator equals to 1 if dyear > 2005 and 0 otherwise.
Show the code
data_firm <- data %>%filter(dyear ==2000) %>%# use `dyear` may create multiple observations for the same firm. E.g. filter(gvkey == 23535, dyear == 2005) select(gvkey, contract_intensity_2000 = contract_intensity) %>%group_by(gvkey) %>%summarise(contract_intensity_2000 =mean(contract_intensity_2000, na.rm =TRUE) ) %>%ungroup() FF_30ind <-as_tibble(read.csv(file ="C:/Users/13613/OneDrive - Handelshögskolan i Stockholm/Projects_2024/BeckerJosephsonXu_2025/AFA_meeting_response/Data/ff_30ind.csv"))data_did <- data %>%## merge the grouping variable left_join(y = data_firm, by =join_by(gvkey) ) %>%## merge the FF 30 industry classifiaction left_join(y = FF_30ind, by =join_by(sic)) %>%## exclude certain industries filter( ff_30ind !=20, # exclude Utiltiy (number 20) !(sic >=6000& sic <=6199) # exclude banks under Banking, Insurance, Real Estate, Trading (number 29) ) %>%## pre- & post- mutate(indexyear = (dyear - base_year), # year index with 2005 as base 0.post_2005 =ifelse(dyear > base_year, yes =1, no =0) # whether it is after the 2005 reform ) # %>% # drop values outside the range:# mutate(# book_leverage = ifelse(test = (book_leverage >= 0 & book_leverage <= 1), yes = book_leverage, no = NA),# debt_ebitda = ifelse(test = (debt_ebitda >= 0 & debt_ebitda <= 15), yes = debt_ebitda, no = NA )# )
DiD Analysis:
Note 3
Q: Do we need to remove IPO and delisting firms?
Important 1: More Fixed-effects
Adding the industry-year fixed effects does not change the regression results.
Show the code
data_did %>%select(gvkey, dyear, contract_intensity_2000, post_2005, book_leverage, debt_ebitda, sic, ff_30ind_name) %>%filter(dyear >=2002& dyear <=2007) %>%mutate(gvkey =as.factor(gvkey), dyear =as.factor(dyear), ind =as.factor(ff_30ind_name), # industry ind_time =as.factor(paste(ff_30ind_name, dyear, sep =" + ")), group = contract_intensity_2000 >median(contract_intensity_2000, na.rm =TRUE) ) %>%na.omit() %>%## adding industry*year FE does not change the results: + ind_time fixest::feols(fml = book_leverage ~ contract_intensity_2000:post_2005 | gvkey + dyear, data = ., cluster =c("gvkey", "ff_30ind_name")) %>% fixest::etable()
In this section, we first try to use the year information fyear extracted from variable datadate as the periods.
On top of the base data, we add several new variables in dataset data_did:
contract_intensity_2000: the contract intensity for each firm in year fyear == 2000.
post_2005: an indicator equals to 1 if fyear > 2005 and 0 otherwise.
Show the code
data_firm <- data %>%filter(fyear ==2000) %>%# use `fyear` may create multiple observations for the same firm. E.g. filter(gvkey == 23535, dyear == 2005) select(gvkey, contract_intensity_2000 = contract_intensity) FF_30ind <-as_tibble(read.csv(file ="C:/Users/13613/OneDrive - Handelshögskolan i Stockholm/Projects_2024/BeckerJosephsonXu_2025/AFA_meeting_response/Data/ff_30ind.csv"))data_did <- data %>%## merge the grouping variable left_join(y = data_firm, by =join_by(gvkey) ) %>%## merge the FF 30 industry classifiaction left_join(y = FF_30ind, by =join_by(sic)) %>%## exclude certain industries filter( ff_30ind !=20, # exclude Utiltiy (number 20) !(sic >=6000& sic <=6199) # exclude banks under Banking, Insurance, Real Estate, Trading (number 29) ) %>%## pre- & post- mutate(indexyear = (fyear - base_year), # year index with 2005 as base 0.post_2005 =ifelse(fyear > base_year, yes =1, no =0) # whether it is after the 2005 reform )
We start by constructing industry-level information.
Show the code
data_firm <- data %>%filter(dyear ==2000) %>%# use `dyear` may create multiple observations for the same firm. E.g. filter(gvkey == 23535, dyear == 2005) select(gvkey, contract_intensity_2000 = contract_intensity) %>%group_by(gvkey) %>%summarise(contract_intensity_2000 =mean(contract_intensity_2000, na.rm =TRUE) ) %>%ungroup()FF_30ind <-as_tibble(read.csv(file ="C:/Users/13613/OneDrive - Handelshögskolan i Stockholm/Projects_2024/BeckerJosephsonXu_2025/AFA_meeting_response/Data/ff_30ind.csv"))## industry level measuresdata_did_ind <- data %>%## merge the grouping variableleft_join(y = data_firm, by =join_by(gvkey) ) %>%## merge the FF 30 industry classifiactionleft_join(y = FF_30ind, by =join_by(sic)) %>%select(gvkey, dyear, contract_intensity, book_leverage, debt_ebitda, sic, ff_30ind, ff_30ind_desc) %>%mutate(ff_30_ind_full =paste(ifelse(ff_30ind <10,yes =paste(" ", ff_30ind, sep =""),no =as.character(ff_30ind)), ff_30ind_desc, sep =": ") ) %>%## for each industry-year:group_by(dyear, ff_30_ind_full, ff_30ind, ff_30ind_desc) %>%summarise(contract_intensity_ind =median(contract_intensity, na.rm =TRUE),book_leverage_ind =median(book_leverage, na.rm =TRUE),debt_ebitda_ind =median(debt_ebitda, na.rm =TRUE) ) %>%ungroup()data_did_ind %>%filter(dyear ==2000& ff_30ind !=20) %>%arrange(-contract_intensity_ind) %>%select(-dyear, -ff_30_ind_full,`FF30 Code`= ff_30ind, # the industry code`Fama-French 30 Industry`= ff_30ind_desc, # name of the`Contract Intensity`= contract_intensity_ind,`Book Leverage`= book_leverage_ind,`Debt-to-EBITDA`= debt_ebitda_ind ) %>%gt(rowname_col ="FF30 Code" ) %>%fmt_number(columns =c(`Contract Intensity`, `Book Leverage`, `Debt-to-EBITDA`),decimals =3 ) %>%tab_header(title ="Table: Contract Intensity by Industry in 2000" ) %>%tab_style(style =cell_text(size ="small"), # Reduce font sizelocations =cells_column_labels(columns =everything()) # reduce the size of tab headers ) %>%tab_style(style =cell_text(size ="small"), # Reduce font sizelocations =cells_body() )
Table: Contract Intensity by Industry in 2000
Fama-French 30 Industry
Contract Intensity
Book Leverage
Debt-to-EBITDA
28
Restaurants, Hotels, Motels
0.566
0.348
2.227
27
Retail
0.538
0.228
1.058
22
Personal and Business Services
0.195
0.061
0.000
25
Transportation
0.188
0.321
2.128
7
Apparel
0.167
0.255
0.735
5
Printing and Publishing
0.137
0.276
1.540
8
Healthcare, Medical Equipment, Pharmaceutical Products
0.131
0.098
0.000
30
Everything Else
0.118
0.276
0.000
26
Wholesale
0.115
0.302
1.921
2
Beer & Liquor
0.115
0.312
0.917
23
Business Equipment
0.114
0.064
0.000
4
Recreation
0.106
0.374
0.940
18
Coal
0.095
0.521
3.799
6
Consumer Goods
0.094
0.307
1.343
13
Fabricated Products and Machinery
0.083
0.260
1.267
10
Textiles
0.079
0.476
3.529
21
Communication
0.079
0.377
0.014
14
Electrical Equipment
0.076
0.216
0.461
16
Aircraft, ships, and railroad equipment
0.075
0.275
1.752
9
Chemicals
0.071
0.313
1.773
24
Business Supplies and Shipping Containers
0.071
0.396
2.564
15
Automobiles and Trucks
0.067
0.363
2.514
1
Food Products
0.065
0.378
2.414
11
Construction and Construction Materials
0.058
0.311
1.754
12
Steel Works Etc
0.056
0.340
3.191
3
Tobacco Products
0.049
0.256
1.208
29
Banking, Insurance, Real Estate, Trading
0.048
0.150
3.215
17
Precious Metals, Non-Metallic, and Industrial Metal Mining
0.042
0.181
0.000
19
Petroleum and Natural Gas
0.028
0.254
0.958
Show the code
## Plot the top and bottom parts:# data_did_ind %>%# ggplot(aes(x = dyear, y = contract_intensity_ind, colour = ff_30_ind_full)) +# geom_line() +# geom_point(aes(shape = ff_30_ind_full)) +# scale_x_continuous(n.breaks = 10, name = NULL)
Then, we perform DiD analysis using the industry-level contract intensity. The hypothesis in this test is that, after the option value of rejecting non-financial obligations decreases, the debt capacity of the firm also decreases. By replacing the contract intensity at the firm level by that at the industry level in 2000, we re-run the standard TWFE regression as in Section 3.
fixest::etable(## industry level difference-in-difference analysis## firm-level dependent variable: data %>%## merge the grouping variableleft_join(y = data_firm, by =join_by(gvkey) ) %>%## merge the FF 30 industry classifiactionleft_join(y = FF_30ind, by =join_by(sic)) %>%select(gvkey, dyear, book_leverage, debt_ebitda, sic, ff_30ind) %>%left_join(y =filter(data_did_ind, dyear ==2000) %>%`names<-`(value =str_replace(string =names(.),pattern ="_ind$",replacement ="_ind2000")) %>%select(-dyear),by =join_by(ff_30ind) ) %>%filter(dyear >=2002& dyear <=2007) %>%mutate(post_2005 =ifelse(dyear > base_year, yes =1, no =0), # whether it is after the 2005 reformgvkey =as.factor(gvkey),dyear =as.factor(dyear),ind =as.factor(ff_30ind), # industryind_time =as.factor(paste(ff_30_ind_full, dyear, sep =" + ")) ) %>%na.omit() %>% fixest::feols(fml = book_leverage ~ contract_intensity_ind2000:post_2005 | gvkey + dyear, data = ., cluster =c("gvkey", "ff_30ind")),## industry-level dependent variable data_did_ind %>%filter(dyear >=2002& dyear <=2007) %>%left_join(y =filter(data_did_ind, dyear ==2000) %>%select(-ff_30_ind_full, -ff_30ind_desc) %>%`names<-`(value =str_replace(string =names(.),pattern ="_ind$",replacement ="_ind2000")) %>%select(-dyear),by =join_by(ff_30ind) ) %>%mutate(post_2005 =ifelse(dyear > base_year, yes =1, no =0), # whether it is after the 2005 reformff_30ind =as.factor(ff_30ind),dyear =as.factor(dyear) ) %>%na.omit() %>% fixest::feols(fml = book_leverage_ind ~ contract_intensity_ind2000:post_2005 | ff_30ind + dyear, data = ., cluster =c("ff_30ind"))) %>% knitr::kable(format ="html", caption ="DiD Results with Industry-level Contract Intensity", col.names =c("", paste("(", 1:2, ")", sep =""))) %>% kableExtra::kable_styling(font_size =8, # Smaller font (default is 16px)full_width =FALSE, # Table width fits contentbootstrap_options =c("striped", "condensed") )
DiD Results with Industry-level Contract Intensity
(1)
(2)
Dependent Var.:
book_leverage
book_leverage_ind
contract_intensity_ind2000 x post_2005
0.9357 (1.703)
0.0739 (0.0543)
Fixed-Effects:
--------------
-----------------
gvkey
Yes
No
dyear
Yes
Yes
ff_30ind
No
Yes
______________________________________
______________
_________________
S.E.: Clustered
by: gvkey & ff_3.
by: ff_30ind
Observations
43,490
180
R2
0.42987
0.87141
Within R2
2.64e-6
0.01510
However, the results show that the industry level evidence is not significant to support the hypothesis. In the regressions using industry-level contact intensities in year 2000 for grouping, the dependent variable is firm level book leverage in regression (1) and industry level median book leverage in regression (2). The coefficient estimates of the interaction term are both positive, which is the opposite of our main regressions. This indicates that the industry-level intensity may not be a good measure for our firm level analysis in Section 3.
For more firm-level analysis for different industries, please refer to Section 5.5.
Appendix
Here are additional tests results with alternative specifications.
A1. Results using different measures of “Net Rental Expenses”
In this part of the analysis, I use the definition of “Net Rental Expenses” in our paper, namely Debt in Current Liabilities (Total) + 3 * xrent and use this to construct a different measure of contract intensity.
A1.1. try-and-error with calender year dyear
In this section, we first try to use the year information dyear extracted from variable datadate as the periods.
On top of the base data, we add several new variables in dataset data_did:
contract_intensity_2000: the contract intensity for each firm in year dyear == 2000.
post_2005: an indicator equals to 1 if dyear > 2005 and 0 otherwise.
Show the code
data_firm <- data %>%filter(dyear ==2000) %>%# use `dyear` may create multiple observations for the same firm. E.g. filter(gvkey == 23535, dyear == 2005) select(gvkey, contract_intensity_2000 = contract_intensity) %>%group_by(gvkey) %>%summarise(contract_intensity_2000 =mean(contract_intensity_2000, na.rm =TRUE) ) %>%ungroup() FF_30ind <-as_tibble(read.csv(file ="C:/Users/13613/OneDrive - Handelshögskolan i Stockholm/Projects_2024/BeckerJosephsonXu_2025/AFA_meeting_response/Data/ff_30ind.csv"))data_did <- data %>%## merge the grouping variable left_join(y = data_firm, by =join_by(gvkey) ) %>%## merge the FF 30 industry classifiaction left_join(y = FF_30ind, by =join_by(sic)) %>%## exclude certain industries filter( ff_30ind !=20, # exclude Utiltiy (number 20) !(sic >=6000& sic <=6199) # exclude banks under Banking, Insurance, Real Estate, Trading (number 29) ) %>%## pre- & post- mutate(indexyear = (dyear - base_year), # year index with 2005 as base 0.post_2005 =ifelse(dyear > base_year, yes =1, no =0) # whether it is after the 2005 reform ) # %>% # drop values outside the range:# mutate(# book_leverage = ifelse(test = (book_leverage >= 0 & book_leverage <= 1), yes = book_leverage, no = NA),# debt_ebitda = ifelse(test = (debt_ebitda >= 0 & debt_ebitda <= 15), yes = debt_ebitda, no = NA )# )
In this section, we first try to use the year information fyear extracted from variable datadate as the periods.
On top of the base data, we add several new variables in dataset data_did:
contract_intensity_2000: the contract intensity for each firm in year fyear == 2000.
post_2005: an indicator equals to 1 if fyear > 2005 and 0 otherwise.
Show the code
data_firm <- data %>%filter(fyear ==2000) %>%# use `fyear` may create multiple observations for the same firm. E.g. filter(gvkey == 23535, dyear == 2005) select(gvkey, contract_intensity_2000 = contract_intensity) FF_30ind <-as_tibble(read.csv(file ="C:/Users/13613/OneDrive - Handelshögskolan i Stockholm/Projects_2024/BeckerJosephsonXu_2025/AFA_meeting_response/Data/ff_30ind.csv"))data_did <- data %>%## merge the grouping variable left_join(y = data_firm, by =join_by(gvkey) ) %>%## merge the FF 30 industry classifiaction left_join(y = FF_30ind, by =join_by(sic)) %>%## exclude certain industries filter( ff_30ind !=20, # exclude Utiltiy (number 20) !(sic >=6000& sic <=6199) # exclude banks under Banking, Insurance, Real Estate, Trading (number 29) ) %>%## pre- & post- mutate(indexyear = (fyear - base_year), # year index with 2005 as base 0.post_2005 =ifelse(fyear > base_year, yes =1, no =0) # whether it is after the 2005 reform ) # %>% # drop values outside the range:# mutate(# book_leverage = ifelse(test = (book_leverage >= 0 & book_leverage <= 1), yes = book_leverage, no = NA),# debt_ebitda = ifelse(test = (debt_ebitda >= 0 & debt_ebitda <= 15), yes = debt_ebitda, no = NA )# )
Compare to results in Section 3.1, the coefficient estimate on the treatment in Section 5.2 not only becomes insignificant, but also changes the direction of the impact.
A3. Sensitivity Analysis of Choosing 2000
In this subsection, we examine how sensitive the coefficient estimate is with respect to changes in the base year for determining the contract intensity of a firm. We still use dyear as the year variable.
Show the code
data_firm_wide <- data %>%select(dyear, gvkey, contract_intensity) %>%group_by(dyear, gvkey) %>%summarise(contract_intensity =mean(contract_intensity, na.rm =TRUE) ) %>%ungroup() %>%filter(dyear <2002) %>%pivot_wider(names_from = dyear, values_from = contract_intensity) %>%rename_with(.fn =~ifelse(grepl(pattern ="\\d{4}", x = .x), paste0("contract_intensity_", .x), no = .x) )data_did_wide <- data %>%## merge the grouping variable left_join(y = data_firm_wide, by =join_by(gvkey) ) %>%## merge the FF 30 industry classifiaction left_join(y = FF_30ind, by =join_by(sic)) %>%## exclude certain industries filter( ff_30ind !=20, # exclude Utiltiy (number 20) !(sic >=6000& sic <=6199) # exclude banks under Banking, Insurance, Real Estate, Trading (number 29) ) %>%## pre- & post- mutate(indexyear = (dyear - base_year), # year index with 2005 as base 0.post_2005 =ifelse(dyear > base_year, yes =1, no =0) # whether it is after the 2005 reform )
We construct a series of new column variables under the name of contract_intensity_[year] with dyear < 2002.
DiD Analysis:
Show the code
reg_contract_intensity_list <-list(); for (contract_base innames(data_firm_wide)[-1] ) {## format the regression reg_raw_year <-as.formula(paste("book_leverage ~ ", contract_base, ":post_2005 | gvkey + dyear", sep ="")) ## use different base year(s) reg_year <- data_did_wide %>%select(gvkey, dyear, post_2005, book_leverage, debt_ebitda, sic, ff_30ind_name, (!!sym(contract_base)) ) %>%filter(dyear >=2002& dyear <=2007) %>%mutate(gvkey =as.factor(gvkey), dyear =as.factor(dyear) ) %>%na.omit() %>% fixest::feols(fml = reg_raw_year, data = ., cluster =c("gvkey", "ff_30ind_name")) reg_contract_intensity_list[[contract_base]] <- reg_yearassign(x =paste("reg_", contract_base, sep =""), reg_year) } ## change the name of each did regressions: names(reg_contract_intensity_list) <-str_replace_all(string =names(reg_contract_intensity_list), pattern ="contract_intensity_", replacement ="base: dyear=")etable(reg_contract_intensity_list, vcov ="cluster") %>% knitr::kable(format ="html", caption ="DiD Results with Different Base Year for Contract Intensity") %>% kableExtra::kable_styling(font_size =8, # Smaller font (default is 16px)full_width =FALSE, # Table width fits content bootstrap_options =c("striped", "condensed") )
DiD Results with Different Base Year for Contract Intensity
From the regression results, we can see that the treatment effect remains negatively statistically significant at 1% level, if we choose 1999 or 2001 as the base year to measure the contract intensity characteristic of a firm. Choosing years before 1999 will make the treatment effect insignificant. This is understandable as firms characteristics before 1999 may not be a good measure for its characteristics between 2002 and 2007. Our results are robust to most of adjustments in the standard errors. In the base tests, results are invariant when we cluster standard errors at the firm level and also at both the firm and year level.
However, the results are no longer significant when we use the heteroscedasticity-robust (HC1) corrected standard errors, even when using 2000 as the base year for contract_intensity. See the regression results below:
Show the code
etable(reg_contract_intensity_list, vcov ="HC1") %>% knitr::kable(format ="html", caption ="DiD Results with Different Base Years for Contract Intensity") %>% kableExtra::kable_styling(font_size =8, # Smaller font (default is 16px)full_width =FALSE, # Table width fits content bootstrap_options =c("striped", "condensed") )
DiD Results with Different Base Years for Contract Intensity
base: dye..1997
base: dyear=1998
base: dy..1999
base: dyear=2000
base: dyear=2001
Dependent Var.:
book_leverage
book_leverage
book_leverage
book_leverage
book_leverage
contract_intensity_1997 x post_2005
0.0676 (0.2919)
contract_intensity_1998 x post_2005
-0.0003 (0.0005)
contract_intensity_1999 x post_2005
-1.797 (1.308)
contract_intensity_2000 x post_2005
-0.4184. (0.2329)
contract_intensity_2001 x post_2005
-0.4592 (0.3001)
Fixed-Effects:
---------------
----------------
--------------
-----------------
----------------
gvkey
Yes
Yes
Yes
Yes
Yes
dyear
Yes
Yes
Yes
Yes
Yes
___________________________________
_______________
________________
______________
_________________
________________
S.E. type
Heteroske.-rob.
Heterosked.-rob.
Heterosk.-rob.
Heteroskeda.-rob.
Heterosked.-rob.
Observations
17,349
19,003
21,231
22,803
24,018
R2
0.31625
0.51764
0.52312
0.39586
0.31542
Within R2
9.14e-7
9.11e-8
0.00434
0.00336
0.00290
The numbers in this test, however, are closer to the ones in Samuel’s slides.
In the last part, we re-run all analyses using fyear as the year variable.
Show the code
## data prep: data_firm_wide_fyear <- data %>%select(fyear, gvkey, contract_intensity) %>%filter(fyear <2002) %>%pivot_wider(names_from = fyear, values_from = contract_intensity) %>%rename_with(.fn =~ifelse(grepl(pattern ="\\d{4}", x = .x), paste0("contract_intensity_", .x), no = .x) )data_did_wide_fyear <- data %>%## merge the grouping variable left_join(y = data_firm_wide_fyear, by =join_by(gvkey) ) %>%## merge the FF 30 industry classifiaction left_join(y = FF_30ind, by =join_by(sic)) %>%## exclude certain industries filter( ff_30ind !=20, # exclude Utiltiy (number 20) !(sic >=6000& sic <=6199) # exclude banks under Banking, Insurance, Real Estate, Trading (number 29) ) %>%## pre- & post- mutate(indexyear = (fyear - base_year), # year index with 2005 as base 0.post_2005 =ifelse(fyear > base_year, yes =1, no =0) # whether it is after the 2005 reform ) ## did reg: reg_contract_intensity_list_fyear <-list(); for (contract_base innames(data_firm_wide)[-1] ) {## format the regression reg_raw_year <-as.formula(paste("book_leverage ~ ", contract_base, ":post_2005 | gvkey + fyear", sep ="")) ## use different base year(s) reg_year <- data_did_wide %>%select(gvkey, fyear, post_2005, book_leverage, debt_ebitda, sic, ff_30ind_name, (!!sym(contract_base)) ) %>%filter(fyear >=2002& fyear <=2007) %>%mutate(gvkey =as.factor(gvkey), fyear =as.factor(fyear) ) %>%na.omit() %>% fixest::feols(fml = reg_raw_year, data = ., cluster =c("gvkey", "ff_30ind_name")) reg_contract_intensity_list_fyear[[contract_base]] <- reg_yearassign(x =paste("reg_", contract_base, sep =""), reg_year) } ## change the name of each did regressions: names(reg_contract_intensity_list_fyear) <-str_replace_all(string =names(reg_contract_intensity_list_fyear), pattern ="contract_intensity_", replacement ="base: fyear=")print("SE clustered at firm level: \n")
[1] "SE clustered at firm level: \n"
Show the code
etable(reg_contract_intensity_list_fyear, cluster =c("gvkey", "ff_30ind_name")) %>% knitr::kable(format ="html", caption ="DiD Results with Different Base Year for Contract Intensity") %>% kableExtra::kable_styling(font_size =8, # Smaller font (default is 16px)full_width =FALSE, # Table width fits content bootstrap_options =c("striped", "condensed") )
DiD Results with Different Base Year for Contract Intensity
base: fye..1997
base: fyear=1998
base: fyear=1999
base: fyear=2000
base: fyear=2001
Dependent Var.:
book_leverage
book_leverage
book_leverage
book_leverage
book_leverage
contract_intensity_1997 x post_2005
0.0139 (0.2941)
contract_intensity_1998 x post_2005
-0.0003 (0.0006)
contract_intensity_1999 x post_2005
-1.781*** (0.2527)
contract_intensity_2000 x post_2005
-0.4244*** (0.1016)
contract_intensity_2001 x post_2005
-0.4708*** (0.0146)
Fixed-Effects:
---------------
----------------
------------------
-------------------
-------------------
gvkey
Yes
Yes
Yes
Yes
Yes
fyear
Yes
Yes
Yes
Yes
Yes
___________________________________
_______________
________________
__________________
___________________
___________________
S.E.: Clustered
by: gvkey & ff_3.
by: gvkey & ff_3.
by: gvkey & ff_3.
by: gvkey & ff_3.
by: gvkey & ff_3.
Observations
17,140
18,782
20,988
22,538
23,739
R2
0.32024
0.52108
0.51044
0.30292
0.26540
Within R2
4.13e-8
1.04e-7
0.00434
0.00112
0.00076
Show the code
print("HC1 robust SE: \n")
[1] "HC1 robust SE: \n"
Show the code
etable(reg_contract_intensity_list_fyear, vcov ="HC1") %>% knitr::kable(format ="html", caption ="DiD Results with Different Base Year for Contract Intensity") %>% kableExtra::kable_styling(font_size =8, # Smaller font (default is 16px)full_width =FALSE, # Table width fits content bootstrap_options =c("striped", "condensed") )
DiD Results with Different Base Year for Contract Intensity
base: fye..1997
base: fyear=1998
base: fy..1999
base: fyear=2000
base: fyear=2001
Dependent Var.:
book_leverage
book_leverage
book_leverage
book_leverage
book_leverage
contract_intensity_1997 x post_2005
0.0139 (0.2737)
contract_intensity_1998 x post_2005
-0.0003 (0.0005)
contract_intensity_1999 x post_2005
-1.781 (1.296)
contract_intensity_2000 x post_2005
-0.4244. (0.2343)
contract_intensity_2001 x post_2005
-0.4708 (0.2999)
Fixed-Effects:
---------------
----------------
--------------
-----------------
----------------
gvkey
Yes
Yes
Yes
Yes
Yes
fyear
Yes
Yes
Yes
Yes
Yes
___________________________________
_______________
________________
______________
_________________
________________
S.E. type
Heteroske.-rob.
Heterosked.-rob.
Heterosk.-rob.
Heteroskeda.-rob.
Heterosked.-rob.
Observations
17,140
18,782
20,988
22,538
23,739
R2
0.32024
0.52108
0.51044
0.30292
0.26540
Within R2
4.13e-8
1.04e-7
0.00434
0.00112
0.00076
In this case, with HC1 standard errors (same as the default in STATA: robust), only the coefficient using 2000 contract intensity is significant at 10% level, which is very close to the results in Samuel’s slides.
Note 4
The reason for not using two-way clustering is that there are only 6 clusters at the time dimension. Fewer than 10–20 clusters in a dimension can lead to biased standard errors (Cameron & Miller, 2015). With 6 years, two-way clustering would produce unreliable results.
A4. Restrict to Firms w/o Missing Values
Show the code
data_firm <- data %>%filter(dyear ==2000) %>%# use `dyear` may create multiple observations for the same firm. E.g. filter(gvkey == 23535, dyear == 2005) select(gvkey, contract_intensity_2000 = contract_intensity) %>%group_by(gvkey) %>%summarise(contract_intensity_2000 =mean(contract_intensity_2000, na.rm =TRUE) ) %>%ungroup() FF_30ind <-as_tibble(read.csv(file ="C:/Users/13613/OneDrive - Handelshögskolan i Stockholm/Projects_2024/BeckerJosephsonXu_2025/AFA_meeting_response/Data/ff_30ind.csv"))data_did <- data %>%## merge the grouping variable left_join(y = data_firm, by =join_by(gvkey) ) %>%## merge the FF 30 industry classifiaction left_join(y = FF_30ind, by =join_by(sic)) %>%## exclude certain industries filter( ff_30ind !=20, # exclude Utiltiy (number 20) !(sic >=6000& sic <=6199) # exclude banks under Banking, Insurance, Real Estate, Trading (number 29) ) %>%## pre- & post- mutate(indexyear = (dyear - base_year), # year index with 2005 as base 0.post_2005 =ifelse(dyear > base_year, yes =1, no =0) # whether it is after the 2005 reform )
Exclude IPO and Delisting
If we drop IPO and delisting firms from the sample, the results are as follows:
Show the code
data_did %>%select(gvkey, dyear, contract_intensity_2000, post_2005, book_leverage, debt_ebitda, sic, ff_30ind_name) %>%filter(dyear >=2002& dyear <=2007) %>%## drop IPO and delisting firmsgroup_by(gvkey) %>%mutate(n_obs =n(), # number of observations for each firmn_post =sum(post_2005, na.rm =TRUE) # number of obs after 2005 ) %>%ungroup() %>%filter(n_obs > n_post & n_post >0) %>%# clean variablesmutate(gvkey =as.factor(gvkey), dyear =as.factor(dyear), ind =as.factor(ff_30ind_name), # industry ind_time =as.factor(paste(ff_30ind_name, dyear, sep =" + ")), group = contract_intensity_2000 >median(contract_intensity_2000, na.rm =TRUE) ) %>%na.omit() %>%## adding industry*year FE does not change the results: + ind_time fixest::feols(fml = book_leverage ~ contract_intensity_2000:post_2005 | gvkey + dyear, data = ., cluster =c("gvkey", "ff_30ind_name")) %>% fixest::etable()
## did analysis for the treatment effects in each industry: did_withind_model <- data_did_withind %>%select(gvkey, dyear, contract_intensity_2000, post_2005, book_leverage, debt_ebitda, sic, ff_30ind_name, ff_30ind_desc, ff_30ind) %>%filter(dyear >=2002& dyear <=2007) %>%mutate(gvkey =as.factor(gvkey), dyear =as.factor(dyear), ff_30ind =as.factor(paste(ff_30ind, ff_30ind_desc, sep =": ")), group = contract_intensity_2000 >median(contract_intensity_2000, na.rm =TRUE) ) %>%na.omit() %>% fixest::feols(fml = book_leverage ~ contract_intensity_2000:post_2005:ff_30ind | gvkey + dyear + ff_30ind^dyear, data = ., cluster =c("gvkey"))did_withind_model %>% fixest::etable()
.
Dependent Var.: book_leverage
contract_intensity_2000 x post_2005 x ff_30ind1 x FoodProducts 2.557 (2.321)
contract_intensity_2000 x post_2005 x ff_30ind10 x Textiles 0.2202 (0.6599)
contract_intensity_2000 x post_2005 x ff_30ind11 x ConstructionandConstructionMaterials 0.3840 (1.948)
contract_intensity_2000 x post_2005 x ff_30ind12 x SteelWorksEtc 0.0945* (0.0372)
contract_intensity_2000 x post_2005 x ff_30ind13 x FabricatedProductsandMachinery -1.343 (0.8874)
contract_intensity_2000 x post_2005 x ff_30ind14 x ElectricalEquipment 1.513 (1.098)
contract_intensity_2000 x post_2005 x ff_30ind15 x AutomobilesandTrucks 24.04*** (1.203)
contract_intensity_2000 x post_2005 x ff_30ind16 x Aircraft,ships,andrailroadequipment 29.67*** (4.386)
contract_intensity_2000 x post_2005 x ff_30ind17 x PreciousMetals,Non-Metallic,andIndustrialMetalMining 63.12 (67.90)
contract_intensity_2000 x post_2005 x ff_30ind18 x Coal -0.3487 (0.5070)
contract_intensity_2000 x post_2005 x ff_30ind19 x PetroleumandNaturalGas -0.4027*** (0.0041)
contract_intensity_2000 x post_2005 x ff_30ind2 x Beer&Liquor 0.7163*** (0.1104)
contract_intensity_2000 x post_2005 x ff_30ind21 x Communication 0.3623 (0.5689)
contract_intensity_2000 x post_2005 x ff_30ind22 x PersonalandBusinessServices -0.3330*** (0.0082)
contract_intensity_2000 x post_2005 x ff_30ind23 x BusinessEquipment -17.50*** (0.6654)
contract_intensity_2000 x post_2005 x ff_30ind24 x BusinessSuppliesandShippingContainers -2.812 (1.908)
contract_intensity_2000 x post_2005 x ff_30ind25 x Transportation -1.039 (1.066)
contract_intensity_2000 x post_2005 x ff_30ind26 x Wholesale -1.617 (4.053)
contract_intensity_2000 x post_2005 x ff_30ind27 x Retail 0.0586 (0.0405)
contract_intensity_2000 x post_2005 x ff_30ind28 x Restaurants,Hotels,Motels 2.457 (2.469)
contract_intensity_2000 x post_2005 x ff_30ind29 x Banking,Insurance,RealEstate,Trading -0.0304 (0.3842)
contract_intensity_2000 x post_2005 x ff_30ind3 x TobaccoProducts -2.974*** (7.57e-14)
contract_intensity_2000 x post_2005 x ff_30ind30 x EverythingElse 1.480 (1.196)
contract_intensity_2000 x post_2005 x ff_30ind4 x Recreation -4.806 (4.700)
contract_intensity_2000 x post_2005 x ff_30ind5 x PrintingandPublishing 171.2 (204.1)
contract_intensity_2000 x post_2005 x ff_30ind6 x ConsumerGoods 0.0226 (0.0278)
contract_intensity_2000 x post_2005 x ff_30ind7 x Apparel -0.0936* (0.0384)
contract_intensity_2000 x post_2005 x ff_30ind8 x Healthcare,MedicalEquipment,PharmaceuticalProducts -2.003*** (0.0754)
contract_intensity_2000 x post_2005 x ff_30ind9 x Chemicals 3.559. (1.836)
Fixed-Effects: --------------------
gvkey Yes
dyear Yes
ff_30ind-dyear Yes
________________________________________ ____________________
S.E.: Clustered by: gvkey
Observations 22,803
R2 0.41325
Within R2 0.02400
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Show the code
fixest::coefplot(did_withind_model,order =str_extract(string =names(sort(coef(did_withind_model), decreasing =FALSE)), pattern ="(?<=ind).*"), horiz =TRUE, drop ="Print", # remove the number 5: Printing & Publishingmain ="Treatment Effect Estimates for Fama-French 30 Industries", sub ="*Printing and Publishing (Industry 5) is excluded. Red dashed line indicates the average treatment effect." ); abline(v = model_a5_average$coefficients, col =2, lty =2, lwd =3)
In this figure, we present the heterogeneous treatment effect of the 2005 policy on the firm leverage across different industries. We include the firm, year and the industry-year fixed effects in the difference-in-difference analysis. We can see that the treatment effect is negative and statistically significant in Business equipment (23), Healthcare (8), Petroleum and Nature Gas (19), Personal and Business Services (22). While the effect is positive and statistically significant in Automobiles and Trucks (15) and Aircraft, ships, and rail road equipment (16).
Healthcare, Medical Equipment, Pharmaceutical Products
13.22
27
1277
Retail
6.57
29
1220
Banking, Insurance, Real Estate, Trading
6.28
30
767
Everything Else
3.95
26
755
Wholesale
3.88
13
706
Fabricated Products and Machinery
3.63
21
624
Communication
3.21
11
581
Construction and Construction Materials
2.99
19
576
Petroleum and Natural Gas
2.96
25
501
Transportation
2.58
28
488
Restaurants, Hotels, Motels
2.51
4
443
Recreation
2.28
9
400
Chemicals
2.06
1
391
Food Products
2.01
7
327
Apparel
1.68
6
271
Consumer Goods
1.39
14
267
Electrical Equipment
1.37
15
251
Automobiles and Trucks
1.29
24
242
Business Supplies and Shipping Containers
1.25
5
214
Printing and Publishing
1.10
16
157
Aircraft, ships, and railroad equipment
0.81
12
155
Steel Works Etc
0.80
10
83
Textiles
0.43
2
71
Beer & Liquor
0.37
17
67
Precious Metals, Non-Metallic, and Industrial Metal Mining
0.34
18
26
Coal
0.13
3
10
Tobacco Products
0.05
This heterogeneous treatment effect is consistent with our hypothesis. The changes in Section 365(d)(4) are mainly on the leases of non-residential real property and thus should have a significant negative impact on the industries with more non-residential real property leases, e.g. industry 8, 23, 22. Its impact on industries with a lot of executory contract unrelated to the real property (e.g. industry 15, 16) should be non-negative.
In the figure, we remove the Industry 5 (Printing & Publishing). Comparing to industries with positive treatment effects, industries with negative treatment effects compose the majority of observations in the sample. This is consistent with our main results in Section 3.1 and in Section 5.4.
A6. Re-run Main Tests with More Filters
In Section 5.2, we find that restricting the dependent variable \in [0,1] significantly impact the treatment effect estimate from the DiD analysis. We therefore re-do main analysis from previous sections.
Dataset without filters (i.e. baseline)
In this setting, we do not put any filters on any variables in the regression. The result is exactly the same as in Section 3.1.
Show the code
rm(list =ls()[! (ls() %in%c("base_year", "compustat_na"))])## create leverage variables data <- compustat_na %>%# filter(at > 0) %>% filter(indfmt =="INDL") %>%## remove all financial firmsmutate(## leverage variables: book_leverage = (dlc + dltt) / at, debt_ebitda = (dlc + dltt) / ebitda, ## treatment intensity: totalrent = mrc1 + mrc2 + mrc3 + mrc4 + mrc5 + mrct, # total rent w/o discount# contract_intensity = (dclo + xrent * 3) / at, # executory contract intensitycontract_intensity = (dclo + totalrent) / at, # executory contract intensity# contract_intensity = (totalrent) / at, # executory contract intensity## other variables: dyear =as.integer(substr(datadate, start =1, stop =4)) # data year ) data_firm <- data %>%filter(dyear ==2000) %>%# use `dyear` may create multiple observations for the same firm. E.g. filter(gvkey == 23535, dyear == 2005) select(gvkey, contract_intensity_2000 = contract_intensity) %>%group_by(gvkey) %>%summarise(contract_intensity_2000 =mean(contract_intensity_2000, na.rm =TRUE) ) %>%ungroup() FF_30ind <-as_tibble(read.csv(file ="C:/Users/13613/OneDrive - Handelshögskolan i Stockholm/Projects_2024/BeckerJosephsonXu_2025/AFA_meeting_response/Data/ff_30ind.csv"))data_did <- data %>%## merge the grouping variable left_join(y = data_firm, by =join_by(gvkey) ) %>%## merge the FF 30 industry classification left_join(y = FF_30ind, by =join_by(sic)) %>%## exclude certain industries filter( ff_30ind !=20, # exclude Utiltiy (number 20) !(sic >=6000& sic <=6199) # exclude banks under Banking, Insurance, Real Estate, Trading (number 29) ) %>%## pre- & post- mutate(indexyear = (dyear - base_year), # year index with 2005 as base 0.post_2005 =ifelse(dyear > base_year, yes =1, no =0) # whether it is after the 2005 reform ) # %>% # # drop values outside the range:# mutate(# book_leverage = ifelse(test = (book_leverage >= 0 & book_leverage <= 1), yes = book_leverage, no = NA),# debt_ebitda = ifelse(test = (debt_ebitda >= 0 & debt_ebitda <= 15), yes = debt_ebitda, no = NA )# )etable(`(1)`= data_did %>%select(gvkey, dyear, contract_intensity_2000, post_2005, book_leverage, debt_ebitda, sic, ff_30ind_name) %>%filter(dyear >=2002& dyear <=2007) %>%mutate(gvkey =as.factor(gvkey), dyear =as.factor(dyear), group = contract_intensity_2000 >median(contract_intensity_2000, na.rm =TRUE) ) %>%na.omit() %>% fixest::feols(fml = book_leverage ~ contract_intensity_2000:post_2005 | gvkey + dyear, data = ., cluster =c("gvkey", "ff_30ind_name")), `(2)`= data_did %>%select(gvkey, dyear, contract_intensity_2000, post_2005, book_leverage, debt_ebitda, sic, ff_30ind_name) %>%filter(dyear >=2002& dyear <=2007) %>%mutate(gvkey =as.factor(gvkey), dyear =as.factor(dyear), group = contract_intensity_2000 >median(contract_intensity_2000, na.rm =TRUE) ) %>%na.omit() %>% fixest::feols(fml = book_leverage ~ contract_intensity_2000:post_2005 | gvkey + dyear + ff_30ind_name^dyear, data = ., cluster =c("gvkey", "ff_30ind_name")) )
vars n mean sd median trimmed mad min max range
book_leverage 1 103021 0.43 4.95 0.19 0.22 0.27 -0.05 843.86 843.91
skew kurtosis se
book_leverage 113.91 15769.32 0.02
Show the code
data_firm <- data %>%filter(dyear ==2000) %>%# use `dyear` may create multiple observations for the same firm. E.g. filter(gvkey == 23535, dyear == 2005) select(gvkey, contract_intensity_2000 = contract_intensity) %>%group_by(gvkey) %>%summarise(contract_intensity_2000 =mean(contract_intensity_2000, na.rm =TRUE) ) %>%ungroup() FF_30ind <-as_tibble(read.csv(file ="C:/Users/13613/OneDrive - Handelshögskolan i Stockholm/Projects_2024/BeckerJosephsonXu_2025/AFA_meeting_response/Data/ff_30ind.csv"))data_did <- data %>%## merge the grouping variable left_join(y = data_firm, by =join_by(gvkey) ) %>%## merge the FF 30 industry classification left_join(y = FF_30ind, by =join_by(sic)) %>%## exclude certain industries filter( ff_30ind !=20, # exclude Utiltiy (number 20) !(sic >=6000& sic <=6199) # exclude banks under Banking, Insurance, Real Estate, Trading (number 29) ) %>%## pre- & post- mutate(indexyear = (dyear - base_year), # year index with 2005 as base 0.post_2005 =ifelse(dyear > base_year, yes =1, no =0) # whether it is after the 2005 reform ) # %>% # # drop values outside the range:# mutate(# book_leverage = ifelse(test = (book_leverage >= 0 & book_leverage <= 1), yes = book_leverage, no = NA),# debt_ebitda = ifelse(test = (debt_ebitda >= 0 & debt_ebitda <= 15), yes = debt_ebitda, no = NA )# )etable(`(1)`= data_did %>%select(gvkey, dyear, contract_intensity_2000, post_2005, book_leverage, debt_ebitda, sic, ff_30ind_name) %>%filter(dyear >=2002& dyear <=2007) %>%mutate(gvkey =as.factor(gvkey), dyear =as.factor(dyear), group = contract_intensity_2000 >median(contract_intensity_2000, na.rm =TRUE) ) %>%na.omit() %>% fixest::feols(fml = book_leverage ~ contract_intensity_2000:post_2005 | gvkey + dyear, data = ., cluster =c("gvkey", "ff_30ind_name")), `(2)`= data_did %>%select(gvkey, dyear, contract_intensity_2000, post_2005, book_leverage, debt_ebitda, sic, ff_30ind_name) %>%filter(dyear >=2002& dyear <=2007) %>%mutate(gvkey =as.factor(gvkey), dyear =as.factor(dyear), group = contract_intensity_2000 >median(contract_intensity_2000, na.rm =TRUE) ) %>%na.omit() %>% fixest::feols(fml = book_leverage ~ contract_intensity_2000:post_2005 | gvkey + dyear + ff_30ind_name^dyear, data = ., cluster =c("gvkey", "ff_30ind_name")) )
vars n mean sd median trimmed mad min max range
book_leverage 1 103021 0.43 4.95 0.19 0.22 0.27 -0.05 843.86 843.91
skew kurtosis se
book_leverage 113.91 15769.32 0.02
Show the code
data_firm <- data %>%filter(dyear ==2000) %>%# use `dyear` may create multiple observations for the same firm. E.g. filter(gvkey == 23535, dyear == 2005) select(gvkey, contract_intensity_2000 = contract_intensity) %>%group_by(gvkey) %>%summarise(contract_intensity_2000 =mean(contract_intensity_2000, na.rm =TRUE) ) %>%ungroup() FF_30ind <-as_tibble(read.csv(file ="C:/Users/13613/OneDrive - Handelshögskolan i Stockholm/Projects_2024/BeckerJosephsonXu_2025/AFA_meeting_response/Data/ff_30ind.csv"))data_did <- data %>%## merge the grouping variable left_join(y = data_firm, by =join_by(gvkey) ) %>%## merge the FF 30 industry classification left_join(y = FF_30ind, by =join_by(sic)) %>%## exclude certain industries filter( ff_30ind !=20, # exclude Utiltiy (number 20) !(sic >=6000& sic <=6199) # exclude banks under Banking, Insurance, Real Estate, Trading (number 29) ) %>%## pre- & post- mutate(indexyear = (dyear - base_year), # year index with 2005 as base 0.post_2005 =ifelse(dyear > base_year, yes =1, no =0) # whether it is after the 2005 reform ) %>%# drop values outside the range:mutate(book_leverage =ifelse(test = (book_leverage >=0& book_leverage <=5), yes = book_leverage, no =NA) )etable(`(1)`= data_did %>%select(gvkey, dyear, contract_intensity_2000, post_2005, book_leverage, debt_ebitda, sic, ff_30ind_name) %>%filter(dyear >=2002& dyear <=2007) %>%mutate(gvkey =as.factor(gvkey), dyear =as.factor(dyear), group = contract_intensity_2000 >median(contract_intensity_2000, na.rm =TRUE) ) %>%na.omit() %>% fixest::feols(fml = book_leverage ~ contract_intensity_2000:post_2005 | gvkey + dyear, data = ., cluster =c("gvkey", "ff_30ind_name")), `(2)`= data_did %>%select(gvkey, dyear, contract_intensity_2000, post_2005, book_leverage, debt_ebitda, sic, ff_30ind_name) %>%filter(dyear >=2002& dyear <=2007) %>%mutate(gvkey =as.factor(gvkey), dyear =as.factor(dyear), group = contract_intensity_2000 >median(contract_intensity_2000, na.rm =TRUE) ) %>%na.omit() %>% fixest::feols(fml = book_leverage ~ contract_intensity_2000:post_2005 | gvkey + dyear + ff_30ind_name^dyear, data = ., cluster =c("gvkey", "ff_30ind_name")) )
vars n mean sd median trimmed mad min max range
book_leverage 1 103021 0.43 4.95 0.19 0.22 0.27 -0.05 843.86 843.91
skew kurtosis se
book_leverage 113.91 15769.32 0.02
Show the code
data_firm <- data %>%filter(dyear ==2000) %>%# use `dyear` may create multiple observations for the same firm. E.g. filter(gvkey == 23535, dyear == 2005) select(gvkey, contract_intensity_2000 = contract_intensity) %>%group_by(gvkey) %>%summarise(contract_intensity_2000 =mean(contract_intensity_2000, na.rm =TRUE) ) %>%ungroup() FF_30ind <-as_tibble(read.csv(file ="C:/Users/13613/OneDrive - Handelshögskolan i Stockholm/Projects_2024/BeckerJosephsonXu_2025/AFA_meeting_response/Data/ff_30ind.csv"))data_did <- data %>%## merge the grouping variable left_join(y = data_firm, by =join_by(gvkey) ) %>%## merge the FF 30 industry classification left_join(y = FF_30ind, by =join_by(sic)) %>%## exclude certain industries filter( ff_30ind !=20, # exclude Utiltiy (number 20) !(sic >=6000& sic <=6199) # exclude banks under Banking, Insurance, Real Estate, Trading (number 29) ) %>%## pre- & post- mutate(indexyear = (dyear - base_year), # year index with 2005 as base 0.post_2005 =ifelse(dyear > base_year, yes =1, no =0) # whether it is after the 2005 reform ) %>%# drop values outside the range:mutate(book_leverage =ifelse(test = (book_leverage >=0& book_leverage <=3), yes = book_leverage, no =NA) )etable(`(1)`= data_did %>%select(gvkey, dyear, contract_intensity_2000, post_2005, book_leverage, debt_ebitda, sic, ff_30ind_name) %>%filter(dyear >=2002& dyear <=2007) %>%mutate(gvkey =as.factor(gvkey), dyear =as.factor(dyear), group = contract_intensity_2000 >median(contract_intensity_2000, na.rm =TRUE) ) %>%na.omit() %>% fixest::feols(fml = book_leverage ~ contract_intensity_2000:post_2005 | gvkey + dyear, data = ., cluster =c("gvkey", "ff_30ind_name")), `(2)`= data_did %>%select(gvkey, dyear, contract_intensity_2000, post_2005, book_leverage, debt_ebitda, sic, ff_30ind_name) %>%filter(dyear >=2002& dyear <=2007) %>%mutate(gvkey =as.factor(gvkey), dyear =as.factor(dyear), group = contract_intensity_2000 >median(contract_intensity_2000, na.rm =TRUE) ) %>%na.omit() %>% fixest::feols(fml = book_leverage ~ contract_intensity_2000:post_2005 | gvkey + dyear + ff_30ind_name^dyear, data = ., cluster =c("gvkey", "ff_30ind_name")) )
vars n mean sd median trimmed mad min max range
book_leverage 1 103021 0.43 4.95 0.19 0.22 0.27 -0.05 843.86 843.91
skew kurtosis se
book_leverage 113.91 15769.32 0.02
Show the code
data_firm <- data %>%filter(dyear ==2000) %>%# use `dyear` may create multiple observations for the same firm. E.g. filter(gvkey == 23535, dyear == 2005) select(gvkey, contract_intensity_2000 = contract_intensity) %>%group_by(gvkey) %>%summarise(contract_intensity_2000 =mean(contract_intensity_2000, na.rm =TRUE) ) %>%ungroup() FF_30ind <-as_tibble(read.csv(file ="C:/Users/13613/OneDrive - Handelshögskolan i Stockholm/Projects_2024/BeckerJosephsonXu_2025/AFA_meeting_response/Data/ff_30ind.csv"))data_did <- data %>%## merge the grouping variable left_join(y = data_firm, by =join_by(gvkey) ) %>%## merge the FF 30 industry classification left_join(y = FF_30ind, by =join_by(sic)) %>%## exclude certain industries filter( ff_30ind !=20, # exclude Utiltiy (number 20) !(sic >=6000& sic <=6199) # exclude banks under Banking, Insurance, Real Estate, Trading (number 29) ) %>%## pre- & post- mutate(indexyear = (dyear - base_year), # year index with 2005 as base 0.post_2005 =ifelse(dyear > base_year, yes =1, no =0) # whether it is after the 2005 reform ) %>%# drop values outside the range:mutate(book_leverage =ifelse(test = (book_leverage >=0& book_leverage <=1), yes = book_leverage, no =NA) )etable(`(1)`= data_did %>%select(gvkey, dyear, contract_intensity_2000, post_2005, book_leverage, debt_ebitda, sic, ff_30ind_name) %>%filter(dyear >=2002& dyear <=2007) %>%mutate(gvkey =as.factor(gvkey), dyear =as.factor(dyear), group = contract_intensity_2000 >median(contract_intensity_2000, na.rm =TRUE) ) %>%na.omit() %>% fixest::feols(fml = book_leverage ~ contract_intensity_2000:post_2005 | gvkey + dyear, data = ., cluster =c("gvkey", "ff_30ind_name")), `(2)`= data_did %>%select(gvkey, dyear, contract_intensity_2000, post_2005, book_leverage, debt_ebitda, sic, ff_30ind_name) %>%filter(dyear >=2002& dyear <=2007) %>%mutate(gvkey =as.factor(gvkey), dyear =as.factor(dyear), group = contract_intensity_2000 >median(contract_intensity_2000, na.rm =TRUE) ) %>%na.omit() %>% fixest::feols(fml = book_leverage ~ contract_intensity_2000:post_2005 | gvkey + dyear + ff_30ind_name^dyear, data = ., cluster =c("gvkey", "ff_30ind_name")) )
## did analysis for the treatment effects in each industry: did_withind_model <- data_did_withind %>%select(gvkey, dyear, contract_intensity_2000, post_2005, book_leverage, debt_ebitda, sic, ff_30ind_name, ff_30ind_desc, ff_30ind) %>%filter(dyear >=2002& dyear <=2007) %>%mutate(gvkey =as.factor(gvkey), dyear =as.factor(dyear), ff_30ind =as.factor(paste(ff_30ind, ff_30ind_desc, sep =": ")), group = contract_intensity_2000 >median(contract_intensity_2000, na.rm =TRUE) ) %>%na.omit() %>% fixest::feols(fml = book_leverage ~ contract_intensity_2000:post_2005:ff_30ind | gvkey + dyear + ff_30ind^dyear, data = ., cluster =c("gvkey"))did_withind_model %>% fixest::etable()
.
Dependent Var.: book_leverage
contract_intensity_2000 x post_2005 x ff_30ind1 x FoodProducts 2.557 (2.321)
contract_intensity_2000 x post_2005 x ff_30ind10 x Textiles 0.2202 (0.6599)
contract_intensity_2000 x post_2005 x ff_30ind11 x ConstructionandConstructionMaterials 0.3840 (1.948)
contract_intensity_2000 x post_2005 x ff_30ind12 x SteelWorksEtc 0.0945* (0.0372)
contract_intensity_2000 x post_2005 x ff_30ind13 x FabricatedProductsandMachinery -1.343 (0.8874)
contract_intensity_2000 x post_2005 x ff_30ind14 x ElectricalEquipment 1.513 (1.098)
contract_intensity_2000 x post_2005 x ff_30ind15 x AutomobilesandTrucks 24.04*** (1.203)
contract_intensity_2000 x post_2005 x ff_30ind16 x Aircraft,ships,andrailroadequipment 29.67*** (4.386)
contract_intensity_2000 x post_2005 x ff_30ind17 x PreciousMetals,Non-Metallic,andIndustrialMetalMining 63.12 (67.90)
contract_intensity_2000 x post_2005 x ff_30ind18 x Coal -0.3487 (0.5070)
contract_intensity_2000 x post_2005 x ff_30ind19 x PetroleumandNaturalGas -0.4027*** (0.0041)
contract_intensity_2000 x post_2005 x ff_30ind2 x Beer&Liquor 0.7163*** (0.1104)
contract_intensity_2000 x post_2005 x ff_30ind21 x Communication 0.3623 (0.5689)
contract_intensity_2000 x post_2005 x ff_30ind22 x PersonalandBusinessServices -0.3330*** (0.0082)
contract_intensity_2000 x post_2005 x ff_30ind23 x BusinessEquipment -17.50*** (0.6654)
contract_intensity_2000 x post_2005 x ff_30ind24 x BusinessSuppliesandShippingContainers -2.812 (1.908)
contract_intensity_2000 x post_2005 x ff_30ind25 x Transportation -1.039 (1.066)
contract_intensity_2000 x post_2005 x ff_30ind26 x Wholesale -1.617 (4.053)
contract_intensity_2000 x post_2005 x ff_30ind27 x Retail 0.0586 (0.0405)
contract_intensity_2000 x post_2005 x ff_30ind28 x Restaurants,Hotels,Motels 2.457 (2.469)
contract_intensity_2000 x post_2005 x ff_30ind29 x Banking,Insurance,RealEstate,Trading -0.0304 (0.3842)
contract_intensity_2000 x post_2005 x ff_30ind3 x TobaccoProducts -2.974*** (7.57e-14)
contract_intensity_2000 x post_2005 x ff_30ind30 x EverythingElse 1.480 (1.196)
contract_intensity_2000 x post_2005 x ff_30ind4 x Recreation -4.806 (4.700)
contract_intensity_2000 x post_2005 x ff_30ind5 x PrintingandPublishing 171.2 (204.1)
contract_intensity_2000 x post_2005 x ff_30ind6 x ConsumerGoods 0.0226 (0.0278)
contract_intensity_2000 x post_2005 x ff_30ind7 x Apparel -0.0936* (0.0384)
contract_intensity_2000 x post_2005 x ff_30ind8 x Healthcare,MedicalEquipment,PharmaceuticalProducts -2.003*** (0.0754)
contract_intensity_2000 x post_2005 x ff_30ind9 x Chemicals 3.559. (1.836)
Fixed-Effects: --------------------
gvkey Yes
dyear Yes
ff_30ind-dyear Yes
________________________________________ ____________________
S.E.: Clustered by: gvkey
Observations 22,803
R2 0.41325
Within R2 0.02400
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Show the code
fixest::coefplot(did_withind_model,order =str_extract(string =names(sort(coef(did_withind_model), decreasing =FALSE)), pattern ="(?<=ind).*"), horiz =TRUE, drop ="Print", # remove the number 5: Printing & Publishingmain ="", sub ="" ); title(main =expression(bold("Treatment Effect Estimates for Fama-French 30 Industries")), adj =0.2); mtext("*Printing and Publishing (Industry 5) is excluded. Red dashed line indicates the average treatment effect.", side =1, line =4, adj =0); abline(v = model_a5_average$coefficients, col =2, lty =2, lwd =3)
For the dataset with filters on book_leverage ∈ [0,1], we re-run all the tests.
Show the code
## create leverage variables data <- compustat_na %>%# filter(at > 0) %>% filter(indfmt =="INDL") %>%## remove all financial firms mutate(## leverage variables: book_leverage = (dlc + dltt) / at, debt_ebitda = (dlc + dltt) / ebitda, ## treatment intensity: totalrent = mrc1 + mrc2 + mrc3 + mrc4 + mrc5 + mrct, # total rent w/o discount# contract_intensity = (dclo + xrent * 3) / at, # executory contract intensitycontract_intensity = (dclo + totalrent) / at, # executory contract intensity## other variables: dyear =as.integer(substr(datadate, start =1, stop =4)) # data year ) data_firm <- data %>%filter(dyear ==2000) %>%# use `dyear` may create multiple observations for the same firm. E.g. filter(gvkey == 23535, dyear == 2005) select(gvkey, contract_intensity_2000 = contract_intensity) %>%group_by(gvkey) %>%summarise(contract_intensity_2000 =mean(contract_intensity_2000, na.rm =TRUE) ) %>%ungroup() FF_30ind <-as_tibble(read.csv(file ="C:/Users/13613/OneDrive - Handelshögskolan i Stockholm/Projects_2024/BeckerJosephsonXu_2025/AFA_meeting_response/Data/ff_30ind.csv"))data_did_withind2 <- data %>%## merge the grouping variable left_join(y = data_firm, by =join_by(gvkey) ) %>%## merge the FF 30 industry classification left_join(y = FF_30ind, by =join_by(sic)) %>%## pre- & post- mutate(indexyear = (dyear - base_year), # year index with 2005 as base 0.post_2005 =ifelse(dyear > base_year, yes =1, no =0) # whether it is after the 2005 reform ) %>%## remove some industries: filter( ff_30ind !=20, # exclude Utiltiy (number 20) !(sic >=6000& sic <=6199) # exclude banks under Banking, Insurance, Real Estate, Trading (number 29) ) %>%# drop values outside the range:mutate(book_leverage =ifelse(test = (book_leverage >=0& book_leverage <=1), yes = book_leverage, no =NA) ) # %>% # ## keep only firms with all observations over the full period. # group_by(gvkey) %>% # mutate(# n_obs = n(), # number of observations for each firm# n_post = sum(post_2005, na.rm = TRUE) # number of obs after 2005# ) %>%# ungroup() %>%# filter(n_obs > n_post & n_post > 0)## did analysis: model_a5_average2 <- data_did_withind2 %>%select(gvkey, dyear, contract_intensity_2000, post_2005, book_leverage, debt_ebitda, sic, ff_30ind_name, ff_30ind_desc, ff_30ind) %>%filter(dyear >=2002& dyear <=2007) %>%mutate(gvkey =as.factor(gvkey), dyear =as.factor(dyear), ff_30ind =as.factor(paste(ff_30ind, ff_30ind_desc, sep =": ")), group = contract_intensity_2000 >median(contract_intensity_2000, na.rm =TRUE) ) %>%na.omit() %>% fixest::feols(fml = book_leverage ~ contract_intensity_2000:post_2005 | gvkey + dyear + ff_30ind^dyear, data = ., cluster =c("gvkey", "ff_30ind_name"))model_a5_average2 %>% fixest::etable()
## did analysis for the treatment effects in each industry: did_withind_model2 <- data_did_withind2 %>%select(gvkey, dyear, contract_intensity_2000, post_2005, book_leverage, debt_ebitda, sic, ff_30ind_name, ff_30ind_desc, ff_30ind) %>%filter(dyear >=2002& dyear <=2007) %>%mutate(gvkey =as.factor(gvkey), dyear =as.factor(dyear), ff_30ind =as.factor(paste(ff_30ind, ff_30ind_desc, sep =": ")), group = contract_intensity_2000 >median(contract_intensity_2000, na.rm =TRUE) ) %>%na.omit() %>% fixest::feols(fml = book_leverage ~ contract_intensity_2000:post_2005:ff_30ind | gvkey + dyear + ff_30ind^dyear, data = ., cluster =c("gvkey"))did_withind_model2 %>% fixest::etable()
.
Dependent Var.: book_leverage
contract_intensity_2000 x post_2005 x ff_30ind1 x FoodProducts -0.0089 (0.0829)
contract_intensity_2000 x post_2005 x ff_30ind10 x Textiles 0.1242 (0.7233)
contract_intensity_2000 x post_2005 x ff_30ind11 x ConstructionandConstructionMaterials -0.0240 (0.0261)
contract_intensity_2000 x post_2005 x ff_30ind12 x SteelWorksEtc 0.0686* (0.0278)
contract_intensity_2000 x post_2005 x ff_30ind13 x FabricatedProductsandMachinery -0.1308 (0.1273)
contract_intensity_2000 x post_2005 x ff_30ind14 x ElectricalEquipment 0.3717** (0.1228)
contract_intensity_2000 x post_2005 x ff_30ind15 x AutomobilesandTrucks -0.3024 (0.2737)
contract_intensity_2000 x post_2005 x ff_30ind16 x Aircraft,ships,andrailroadequipment -0.4004 (0.2792)
contract_intensity_2000 x post_2005 x ff_30ind17 x PreciousMetals,Non-Metallic,andIndustrialMetalMining -0.2696 (0.3718)
contract_intensity_2000 x post_2005 x ff_30ind18 x Coal -0.3487 (0.5071)
contract_intensity_2000 x post_2005 x ff_30ind19 x PetroleumandNaturalGas 0.0263*** (0.0027)
contract_intensity_2000 x post_2005 x ff_30ind2 x Beer&Liquor 0.7163*** (0.1104)
contract_intensity_2000 x post_2005 x ff_30ind21 x Communication -0.0166 (0.0234)
contract_intensity_2000 x post_2005 x ff_30ind22 x PersonalandBusinessServices -0.0280 (0.0272)
contract_intensity_2000 x post_2005 x ff_30ind23 x BusinessEquipment 0.0060*** (0.0015)
contract_intensity_2000 x post_2005 x ff_30ind24 x BusinessSuppliesandShippingContainers -0.0471 (0.1226)
contract_intensity_2000 x post_2005 x ff_30ind25 x Transportation -0.0082 (0.0177)
contract_intensity_2000 x post_2005 x ff_30ind26 x Wholesale -0.0394 (0.0467)
contract_intensity_2000 x post_2005 x ff_30ind27 x Retail 0.0106 (0.0129)
contract_intensity_2000 x post_2005 x ff_30ind28 x Restaurants,Hotels,Motels -0.0222 (0.0303)
contract_intensity_2000 x post_2005 x ff_30ind29 x Banking,Insurance,RealEstate,Trading 0.0416 (0.0462)
contract_intensity_2000 x post_2005 x ff_30ind3 x TobaccoProducts -2.974*** (2.05e-16)
contract_intensity_2000 x post_2005 x ff_30ind30 x EverythingElse 0.0072 (0.0307)
contract_intensity_2000 x post_2005 x ff_30ind4 x Recreation 0.1603* (0.0749)
contract_intensity_2000 x post_2005 x ff_30ind5 x PrintingandPublishing 0.1978 (0.1655)
contract_intensity_2000 x post_2005 x ff_30ind6 x ConsumerGoods 0.0127 (0.0295)
contract_intensity_2000 x post_2005 x ff_30ind7 x Apparel -0.0755* (0.0317)
contract_intensity_2000 x post_2005 x ff_30ind8 x Healthcare,MedicalEquipment,PharmaceuticalProducts 0.0012 (0.0012)
contract_intensity_2000 x post_2005 x ff_30ind9 x Chemicals -0.3381* (0.1453)
Fixed-Effects: --------------------
gvkey Yes
dyear Yes
ff_30ind-dyear Yes
________________________________________ ____________________
S.E.: Clustered by: gvkey
Observations 21,599
R2 0.79900
Within R2 0.00481
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Show the code
fixest::coefplot(did_withind_model2,order =str_extract(string =names(sort(coef(did_withind_model2), decreasing =FALSE)), pattern ="(?<=ind).*"), horiz =TRUE, drop ="Print", # remove the number 5: Printing & Publishingmain ="", sub ="" ); title(main =expression(bold("Treatment Effect Estimates for Fama-French 30 Industries (Book leverage"%in%"[0,1])")), adj =0.2); mtext("*Printing and Publishing (Industry 5) is excluded. Red dashed line indicates the average treatment effect.", side =1, line =4, adj =0); abline(v = model_a5_average2$coefficients, col =2, lty =2, lwd =3)
The industry-by-industry estimates show that observations for ff_30ind == 8, 22, 23 (Healthcare, Medical Equipment, Pharmaceutical Products; Personal and Business Services; Business Equipment) are significantly reduced and this contributes to the change in the average treatment effect estimate in Section 5.2.
We also compare the treatment effects from the two samples:
as the coefficient estimates for industry 5 are too large, they are excluded in the following graph.
Show the code
fixest::coefplot(list(did_withind_model, did_withind_model2), order =paste("ind", sort(as.numeric(str_extract(names(coef(did_withind_model2)), pattern ="(?<=ind)[^:]+"))), ":", sep =""), horiz =TRUE, drop ="Print", # remove the number 5: Printing & Publishingmain ="", sub ="", sep =0.3 ); title(main =expression(bold("Treatment Effect Estimates for Fama-French 30 Industries")), adj =0.2); mtext("*Printing and Publishing (Industry 5) is excluded. Red dashed line indicates the average treatment effect.", side =1, line =4, adj =0); legend("bottomleft", bty ="n", col =c(1, 2), pch =c(20, 17), legend =c("Full Sample", expression("Book leverage"%in%"[0,1]")))
We also check the impact of this filter, book_leverage ∈ [0,1], on the sample. The left table below gives the number of firm-year observations for each industry in the full sample and the right one gives the number of observations for each industry in the filter sample. We can see a decrease in the number of observations in the three industries, 8, 22 and 23, after applying the filter. These three industries happen to be the ones contribute most to the average treatment effect.
Show the code
tbl_count1 <- data %>%## merge the grouping variable left_join(y = data_firm, by =join_by(gvkey) ) %>%## merge the FF 30 industry classification left_join(y = FF_30ind, by =join_by(sic)) %>%## remove some industries: filter( ff_30ind !=20, # exclude Utiltiy (number 20) !(sic >=6000& sic <=6199) # exclude banks under Banking, Insurance, Real Estate, Trading (number 29) ) %>%filter(dyear >=2002& dyear <=2007) %>%na.omit() %>%group_by(ff_30ind) %>%summarise(n_obs =n(), ff_30ind_name =unique(ff_30ind_desc)) %>%ungroup() %>%mutate(`n_per %`=round(n_obs /sum(n_obs) *100, digits =2)) %>%arrange(-n_obs) %>%gt() %>%tab_spanner(label ="(1) Full Sample",columns =c(n_obs, `n_per %`) ) %>%tab_style(style =cell_text(size ="x-small"), # Reduce font sizelocations =cells_column_labels(columns =everything()) # reduce the size of tab headers ) %>%tab_style(style =cell_text(size ="x-small"), # Reduce font sizelocations =cells_body() ) tbl_count1tbl_count2 <- data_did_withind2 %>%filter(dyear >=2002& dyear <=2007) %>%na.omit() %>%group_by(ff_30ind) %>%summarise(n_obs =n(), ff_30ind_name =unique(ff_30ind_desc)) %>%ungroup() %>%mutate(`n_per %`=round(n_obs /sum(n_obs) *100, digits =2)) %>%arrange(-n_obs) %>%gt() %>%tab_spanner(label =html("(2) book leverage ∈ [0,1]"), columns =c(n_obs, `n_per %`) ) %>%tab_style(style =cell_text(size ="x-small"), # Reduce font sizelocations =cells_column_labels(columns =everything()) # reduce the size of tab headers ) %>%tab_style(style =cell_text(size ="x-small"), # Reduce font sizelocations =cells_body() ) tbl_count2
ff_30ind
(1) Full Sample
ff_30ind_name
n_obs
n_per %
22
3277
16.86
Personal and Business Services
23
2717
13.98
Business Equipment
8
2570
13.22
Healthcare, Medical Equipment, Pharmaceutical Products
27
1277
6.57
Retail
29
1220
6.28
Banking, Insurance, Real Estate, Trading
30
767
3.95
Everything Else
26
755
3.88
Wholesale
13
706
3.63
Fabricated Products and Machinery
21
624
3.21
Communication
11
581
2.99
Construction and Construction Materials
19
576
2.96
Petroleum and Natural Gas
25
501
2.58
Transportation
28
488
2.51
Restaurants, Hotels, Motels
4
443
2.28
Recreation
9
400
2.06
Chemicals
1
391
2.01
Food Products
7
327
1.68
Apparel
6
271
1.39
Consumer Goods
14
267
1.37
Electrical Equipment
15
251
1.29
Automobiles and Trucks
24
242
1.25
Business Supplies and Shipping Containers
5
214
1.10
Printing and Publishing
16
157
0.81
Aircraft, ships, and railroad equipment
12
155
0.80
Steel Works Etc
10
83
0.43
Textiles
2
71
0.37
Beer & Liquor
17
67
0.34
Precious Metals, Non-Metallic, and Industrial Metal Mining
18
26
0.13
Coal
3
10
0.05
Tobacco Products
ff_30ind
(2) book leverage ∈ [0,1]
ff_30ind_name
n_obs
n_per %
22
3131
16.86
Personal and Business Services
23
2615
14.08
Business Equipment
8
2439
13.13
Healthcare, Medical Equipment, Pharmaceutical Products
27
1251
6.74
Retail
29
1183
6.37
Banking, Insurance, Real Estate, Trading
26
737
3.97
Wholesale
30
682
3.67
Everything Else
13
669
3.60
Fabricated Products and Machinery
11
563
3.03
Construction and Construction Materials
19
560
3.02
Petroleum and Natural Gas
21
547
2.95
Communication
25
495
2.67
Transportation
28
469
2.53
Restaurants, Hotels, Motels
4
419
2.26
Recreation
1
384
2.07
Food Products
9
371
2.00
Chemicals
7
322
1.73
Apparel
14
260
1.40
Electrical Equipment
6
249
1.34
Consumer Goods
15
241
1.30
Automobiles and Trucks
24
232
1.25
Business Supplies and Shipping Containers
5
201
1.08
Printing and Publishing
12
153
0.82
Steel Works Etc
16
146
0.79
Aircraft, ships, and railroad equipment
10
79
0.43
Textiles
2
71
0.38
Beer & Liquor
17
66
0.36
Precious Metals, Non-Metallic, and Industrial Metal Mining
18
26
0.14
Coal
3
10
0.05
Tobacco Products
To further validate our conjecture that the filter affecting different industries unequally, we remove all firms which contain book_leverage outside the [0,1] range. We re-do the main analysis and the industry level analysis on a balanced panel:
Show the code
## create leverage variables data <- compustat_na %>%# filter(at > 0) %>% filter(indfmt =="INDL") %>%## remove all financial firms mutate(## leverage variables: book_leverage = (dlc + dltt) / at, debt_ebitda = (dlc + dltt) / ebitda, ## treatment intensity: totalrent = mrc1 + mrc2 + mrc3 + mrc4 + mrc5 + mrct, # total rent w/o discount# contract_intensity = (dclo + xrent * 3) / at, # executory contract intensitycontract_intensity = (dclo + totalrent) / at, # executory contract intensity## other variables: dyear =as.integer(substr(datadate, start =1, stop =4)) # data year ) data_firm <- data %>%filter(dyear ==2000) %>%# use `dyear` may create multiple observations for the same firm. E.g. filter(gvkey == 23535, dyear == 2005) select(gvkey, contract_intensity_2000 = contract_intensity) %>%group_by(gvkey) %>%summarise(contract_intensity_2000 =mean(contract_intensity_2000, na.rm =TRUE) ) %>%ungroup() FF_30ind <-as_tibble(read.csv(file ="C:/Users/13613/OneDrive - Handelshögskolan i Stockholm/Projects_2024/BeckerJosephsonXu_2025/AFA_meeting_response/Data/ff_30ind.csv"))data_did_withind3 <- data %>%## merge the grouping variable left_join(y = data_firm, by =join_by(gvkey) ) %>%## merge the FF 30 industry classification left_join(y = FF_30ind, by =join_by(sic)) %>%## pre- & post- mutate(indexyear = (dyear - base_year), # year index with 2005 as base 0.post_2005 =ifelse(dyear > base_year, yes =1, no =0) # whether it is after the 2005 reform ) %>%## remove some industries: filter( ff_30ind !=20, # exclude Utiltiy (number 20) ff_30ind !=5, # exclude (number 5) fic =="USA", !(sic >=6000& sic <=6199) # exclude banks under Banking, Insurance, Real Estate, Trading (number 29) ) %>%# drop values outside the range:mutate(book_leverage =ifelse(test = (book_leverage >=0& book_leverage <=1), yes = book_leverage, no =NA) ) ## did analysis: data_did_withind3 %>%select(gvkey, dyear, contract_intensity_2000, post_2005, book_leverage, debt_ebitda, sic, ff_30ind, ff_30ind_name) %>%filter(dyear >=2002& dyear <=2007) %>%## keep only firms with all observations over the full period.na.omit() %>%group_by(gvkey) %>%mutate(n_obs =n(), # number of observations for each firmn_post =sum(post_2005, na.rm =TRUE) # number of obs after 2005 ) %>%ungroup() %>%filter(n_obs >=6) %>%## re-clean mutate(gvkey =as.factor(gvkey) ) %>%na.omit() %>% fixest::feols(fml = book_leverage ~ contract_intensity_2000:post_2005 | gvkey + dyear + ff_30ind^dyear, data = ., cluster =c("gvkey", "ff_30ind_name")) %>% fixest::etable()
## did analysis for the treatment effects in each industry: did_withind_model3 <- data_did_withind3 %>%select(gvkey, dyear, contract_intensity_2000, post_2005, book_leverage, debt_ebitda, sic, ff_30ind_name, ff_30ind_desc, ff_30ind) %>%filter(dyear >=2002& dyear <=2007) %>%## keep only firms with all observations over the full period.na.omit() %>%group_by(gvkey) %>%mutate(n_obs =n(), # number of observations for each firmn_post =sum(post_2005, na.rm =TRUE) # number of obs after 2005 ) %>%ungroup() %>%filter(n_obs >=6) %>%## mutate(gvkey =as.factor(gvkey), ff_30ind =as.factor(paste(ff_30ind, ff_30ind_desc, sep =": ")), group = contract_intensity_2000 >median(contract_intensity_2000, na.rm =TRUE) ) %>%na.omit() %>% fixest::feols(fml = book_leverage ~ contract_intensity_2000:post_2005:ff_30ind | gvkey + dyear + ff_30ind^dyear, data = ., cluster =c("gvkey"))model_a5_average3 <- data_did_withind3 %>%select(gvkey, dyear, contract_intensity_2000, post_2005, book_leverage, debt_ebitda, sic, ff_30ind_name, ff_30ind_desc, ff_30ind) %>%filter(dyear >=2002& dyear <=2007) %>%## keep only firms with all observations over the full period.na.omit() %>%group_by(gvkey) %>%mutate(n_obs =n(), # number of observations for each firmn_post =sum(post_2005, na.rm =TRUE) # number of obs after 2005 ) %>%ungroup() %>%filter(n_obs >=6) %>%## mutate(gvkey =as.factor(gvkey), ff_30ind =as.factor(paste(ff_30ind, ff_30ind_desc, sep =": ")), group = contract_intensity_2000 >median(contract_intensity_2000, na.rm =TRUE) ) %>%na.omit() %>% fixest::feols(fml = book_leverage ~ contract_intensity_2000:post_2005 | gvkey + dyear + sic^dyear, data = ., cluster =c("gvkey", "ff_30ind_name"))did_withind_model3 %>% fixest::etable()
.
Dependent Var.: book_leverage
contract_intensity_2000 x post_2005 x ff_30ind1 x FoodProducts 0.0604 (0.0738)
contract_intensity_2000 x post_2005 x ff_30ind10 x Textiles 0.2196 (0.7334)
contract_intensity_2000 x post_2005 x ff_30ind11 x ConstructionandConstructionMaterials -0.0205 (0.0245)
contract_intensity_2000 x post_2005 x ff_30ind12 x SteelWorksEtc 0.0470 (0.0302)
contract_intensity_2000 x post_2005 x ff_30ind13 x FabricatedProductsandMachinery -0.0556 (0.1267)
contract_intensity_2000 x post_2005 x ff_30ind14 x ElectricalEquipment 0.4162*** (0.1213)
contract_intensity_2000 x post_2005 x ff_30ind15 x AutomobilesandTrucks -0.2071 (0.2629)
contract_intensity_2000 x post_2005 x ff_30ind16 x Aircraft,ships,andrailroadequipment -0.3590 (0.2775)
contract_intensity_2000 x post_2005 x ff_30ind17 x PreciousMetals,Non-Metallic,andIndustrialMetalMining -0.3417 (1.645)
contract_intensity_2000 x post_2005 x ff_30ind18 x Coal -0.3487 (0.5080)
contract_intensity_2000 x post_2005 x ff_30ind19 x PetroleumandNaturalGas 0.2578*** (0.0543)
contract_intensity_2000 x post_2005 x ff_30ind2 x Beer&Liquor 0.7163*** (0.1106)
contract_intensity_2000 x post_2005 x ff_30ind21 x Communication -0.0220 (0.0208)
contract_intensity_2000 x post_2005 x ff_30ind22 x PersonalandBusinessServices -0.0351 (0.0316)
contract_intensity_2000 x post_2005 x ff_30ind23 x BusinessEquipment 0.0206 (0.0317)
contract_intensity_2000 x post_2005 x ff_30ind24 x BusinessSuppliesandShippingContainers -0.1955 (0.2194)
contract_intensity_2000 x post_2005 x ff_30ind25 x Transportation 0.0172 (0.0123)
contract_intensity_2000 x post_2005 x ff_30ind26 x Wholesale -0.0344 (0.0411)
contract_intensity_2000 x post_2005 x ff_30ind27 x Retail 0.0060 (0.0130)
contract_intensity_2000 x post_2005 x ff_30ind28 x Restaurants,Hotels,Motels -0.0194 (0.0367)
contract_intensity_2000 x post_2005 x ff_30ind29 x Banking,Insurance,RealEstate,Trading -0.0034 (0.0351)
contract_intensity_2000 x post_2005 x ff_30ind3 x TobaccoProducts -2.974*** (4.44e-16)
contract_intensity_2000 x post_2005 x ff_30ind30 x EverythingElse 0.0336 (0.0290)
contract_intensity_2000 x post_2005 x ff_30ind4 x Recreation 0.2530*** (0.0512)
contract_intensity_2000 x post_2005 x ff_30ind6 x ConsumerGoods 0.0175 (0.0298)
contract_intensity_2000 x post_2005 x ff_30ind7 x Apparel -0.0687* (0.0318)
contract_intensity_2000 x post_2005 x ff_30ind8 x Healthcare,MedicalEquipment,PharmaceuticalProducts -0.0624** (0.0217)
contract_intensity_2000 x post_2005 x ff_30ind9 x Chemicals -0.3987** (0.1323)
Fixed-Effects: --------------------
gvkey Yes
dyear Yes
ff_30ind-dyear Yes
________________________________________ ____________________
S.E.: Clustered by: gvkey
Observations 15,449
R2 0.78236
Within R2 0.00795
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Show the code
fixest::coefplot(did_withind_model3,order =str_extract(string =names(sort(coef(did_withind_model3), decreasing =FALSE)), pattern ="(?<=ind).*"), horiz =TRUE, drop ="Print", # remove the number 5: Printing & Publishingmain ="", sub ="" ); title(main =expression(bold("Treatment Effect Estimates for Fama-French 30 Industries (Book leverage"%in%"[0,1] & Balanced Panel)")), adj =0.2); mtext("*Printing and Publishing (Industry 5) is excluded. Red dashed line indicates the average treatment effect.", side =1, line =4, adj =0); abline(v = model_a5_average3$coefficients, col =2, lty =2, lwd =3)
The average treatment effect estimate is negative but insignificant in the filtered sample. In particular, we have seen a large change in the treatment effect estimate in industries 8 and 23. As these industries consist of most of the observations in our sample (over 25%), this significantly reduce the magnitude of the average treatment effect estimate in the sample and make it insignificant.
In this subsection, let’s look into the dynamics of those excluded observations:
Show the code
## data prep: data_did_withind3 <- data %>%## merge the grouping variable left_join(y = data_firm, by =join_by(gvkey) ) %>%## merge the FF 30 industry classification left_join(y = FF_30ind, by =join_by(sic)) %>%## pre- & post- mutate(indexyear = (dyear - base_year), # year index with 2005 as base 0.post_2005 =ifelse(dyear > base_year, yes =1, no =0) # whether it is after the 2005 reform ) %>%## remove some industries: filter( ff_30ind !=20, # exclude Utiltiy (number 20) ff_30ind !=5, # exclude (number 5) !(sic >=6000& sic <=6199) # exclude banks under Banking, Insurance, Real Estate, Trading (number 29) ) %>%# drop values outside the range:mutate(book_leverage_filter =ifelse(test = (book_leverage >=0& book_leverage <=1), yes = book_leverage, no =NA) ) data_did_withind3 %>%filter(is.na(book_leverage_filter)) %>%filter(dyear >=2000& dyear <=2007&!is.na(book_leverage) &!is.na(contract_intensity_2000)) %>%select(conm, tic, # tic, cik, fic, dyear, # fyear, datadate,ci_2000 = contract_intensity_2000, book_leverage, at, dlc, dltt, ff_30ind_name)
## boxplot data_did_withind3 %>%select(gvkey, dyear, contract_intensity_2000, post_2005, book_leverage, debt_ebitda, sic, ff_30ind, ff_30ind_name, book_leverage_filter) %>%filter(dyear >=2002& dyear <=2007) %>%## keep only firms with all observations over the full period.# na.omit() %>% group_by(gvkey) %>%mutate(n_obs =sum(!is.na(book_leverage_filter)), # number of non-NA observations for each firm n_post =sum(post_2005, na.rm =TRUE) # number of obs after 2005 ) %>%ungroup() %>%filter(n_obs <6) %>%mutate(dyear =as.factor(dyear) ) %>%ggplot(data = ., aes(x = dyear, y = book_leverage)) +## box plotgeom_boxplot(notch =FALSE, outlier.shape =4) +## add dot plotgeom_dotplot(binaxis ="y",binwidth =1/50,position =position_jitter(width =0, height =0.1, seed =123),stackdir ="center",dotsize =0.3)
Warning: Removed 6911 rows containing non-finite outside the scale range
(`stat_boxplot()`).
Warning: Removed 6762 rows containing missing values or values outside the scale range
(`stat_bindot()`).
Show the code
## violin data_did_withind3 %>%select(gvkey, dyear, contract_intensity_2000, post_2005, book_leverage, debt_ebitda, sic, ff_30ind, ff_30ind_name) %>%filter(dyear >=2002& dyear <=2007) %>%## keep only firms with all observations over the full period.na.omit() %>%group_by(gvkey) %>%mutate(n_obs =n(), # number of observations for each firmn_post =sum(post_2005, na.rm =TRUE) # number of obs after 2005 ) %>%ungroup() %>%filter(n_obs <6) %>%mutate(dyear =as.factor(dyear) ) %>%ggplot(data = ., aes(x = dyear, y = book_leverage)) +geom_violin()
Warning: Removed 28 rows containing non-finite outside the scale range
(`stat_ydensity()`).
Show the code
## density data_did_withind3 %>%select(gvkey, dyear, contract_intensity_2000, post_2005, book_leverage, debt_ebitda, sic, ff_30ind, ff_30ind_name) %>%filter(dyear >=2002& dyear <=2007) %>%## keep only firms with all observations over the full period.na.omit() %>%group_by(gvkey) %>%mutate(n_obs =n(), # number of observations for each firmn_post =sum(post_2005, na.rm =TRUE) # number of obs after 2005 ) %>%ungroup() %>%filter(n_obs <6) %>%mutate(dyear =as.factor(dyear) ) %>%ggplot(., aes(x = book_leverage, color =factor(dyear)) ) +geom_density(alpha =0.3) +labs(x ="Book Leverage", y ="Density", title ="Density Plot of Book Leverage by Year") +theme_minimal() +theme(legend.title =element_blank())
Warning: Removed 28 rows containing non-finite outside the scale range
(`stat_density()`).
Show the code
cat("More tests: use `debt_ebitda` ratio as the dependent variable ")
More tests: use `debt_ebitda` ratio as the dependent variable
Show the code
## did analysis: data_did_withind %>%select(gvkey, dyear, contract_intensity_2000, post_2005, book_leverage, debt_ebitda, sic, ff_30ind, ff_30ind_name) %>%mutate(book_leverage =ifelse(test = (book_leverage >=0& book_leverage <=1), yes = book_leverage, no =NA),debt_ebitda =ifelse(test = (debt_ebitda >=0& debt_ebitda <=15), yes = debt_ebitda, no =NA ) ) %>%filter(dyear >=2002& dyear <=2007) %>%## keep only firms with all observations over the full period.na.omit() %>%group_by(gvkey) %>%mutate(n_obs =n(), # number of observations for each firmn_post =sum(post_2005, na.rm =TRUE) # number of obs after 2005 ) %>%ungroup() %>%# filter(n_obs == 6) %>% ## re-clean mutate(gvkey =as.factor(gvkey) ) %>%na.omit() %>% fixest::feols(fml = debt_ebitda ~ contract_intensity_2000:post_2005 | gvkey + dyear + ff_30ind^dyear, data = ., cluster =c("gvkey", "ff_30ind_name")) %>% fixest::etable()