diff --git a/input_processing/labour_supply/do-files/ADO/add_father_variables.ado b/input_processing/labour_supply/do-files/ADO/add_father_variables.ado new file mode 100644 index 0000000..e179d8d --- /dev/null +++ b/input_processing/labour_supply/do-files/ADO/add_father_variables.ado @@ -0,0 +1,29 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//PROGRAM TO ATTACH PARTNER VARIABLES TO THE RESPONDENT // +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +program define add_father_variables + args father_vars //assign arguments to local macros + + preserve // Preserve the original dataset + keep idperson `father_vars' + rename idperson idfather + + tokenize `father_vars' // Split partner_vars into a list and store each resulting token in a numbered local macro. + while "`1'" != "" { // Loop over each variable and rename + capture confirm variable `1' // Check if the variable exists in the dataset + if !_rc { + rename `1' father_`1' + } + macro shift //process each token in a loop + } + sort idfather + + save "${local_data}/temp_father", replace // Save the modified dataset to a temporary file + restore // Restore the original dataset + + sort idfather + merge m:1 idfather using "${local_data}/temp_father" // Merge the temporary dataset to original , m:1 because idfather can be zero for many + keep if _merge == 1 | _merge == 3 + drop _merge +end +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/input_processing/labour_supply/do-files/ADO/add_father_variables2.ado b/input_processing/labour_supply/do-files/ADO/add_father_variables2.ado new file mode 100644 index 0000000..e7941f7 --- /dev/null +++ b/input_processing/labour_supply/do-files/ADO/add_father_variables2.ado @@ -0,0 +1,29 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//PROGRAM TO ATTACH PARTNER VARIABLES TO THE RESPONDENT // +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +program define add_father_variables2 + args father_vars //assign arguments to local macros + + preserve // Preserve the original dataset + keep stm idperson `father_vars' + rename idperson idfather + + tokenize `father_vars' // Split partner_vars into a list and store each resulting token in a numbered local macro. + while "`1'" != "" { // Loop over each variable and rename + capture confirm variable `1' // Check if the variable exists in the dataset + if !_rc { + rename `1' father_`1' + } + macro shift //process each token in a loop + } + sort stm idfather + + save "${local_data}/temp_father", replace // Save the modified dataset to a temporary file + restore // Restore the original dataset + + sort stm idfather + merge m:1 stm idfather using "${local_data}/temp_father" // Merge the temporary dataset to original , m:1 because idfather can be zero for many + keep if _merge == 1 | _merge == 3 + drop _merge +end +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/input_processing/labour_supply/do-files/ADO/add_mother_variables.ado b/input_processing/labour_supply/do-files/ADO/add_mother_variables.ado new file mode 100644 index 0000000..dcd251f --- /dev/null +++ b/input_processing/labour_supply/do-files/ADO/add_mother_variables.ado @@ -0,0 +1,29 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//PROGRAM TO ATTACH PARTNER VARIABLES TO THE RESPONDENT // +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +program define add_mother_variables + args mother_vars //assign arguments to local macros + + preserve // Preserve the original dataset + keep idperson `mother_vars' + rename idperson idmother + + tokenize `mother_vars' // Split partner_vars into a list and store each resulting token in a numbered local macro. + while "`1'" != "" { // Loop over each variable and rename + capture confirm variable `1' // Check if the variable exists in the dataset + if !_rc { + rename `1' mother_`1' + } + macro shift //process each token in a loop + } + sort idmother + + save "${local_data}/temp_mother", replace // Save the modified dataset to a temporary file + restore // Restore the original dataset + + sort idmother + merge m:1 idmother using "${local_data}/temp_mother" // Merge the temporary dataset to original , m:1 because idmother can be zero for many + keep if _merge == 1 | _merge == 3 + drop _merge +end +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/input_processing/labour_supply/do-files/ADO/add_mother_variables2.ado b/input_processing/labour_supply/do-files/ADO/add_mother_variables2.ado new file mode 100644 index 0000000..ce9bea5 --- /dev/null +++ b/input_processing/labour_supply/do-files/ADO/add_mother_variables2.ado @@ -0,0 +1,29 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//PROGRAM TO ATTACH PARTNER VARIABLES TO THE RESPONDENT // +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +program define add_mother_variables2 + args mother_vars //assign arguments to local macros + + preserve // Preserve the original dataset + keep stm idperson `mother_vars' + rename idperson idmother + + tokenize `mother_vars' // Split partner_vars into a list and store each resulting token in a numbered local macro. + while "`1'" != "" { // Loop over each variable and rename + capture confirm variable `1' // Check if the variable exists in the dataset + if !_rc { + rename `1' mother_`1' + } + macro shift //process each token in a loop + } + sort stm idmother + + save "${local_data}/temp_mother", replace // Save the modified dataset to a temporary file + restore // Restore the original dataset + + sort stm idmother + merge m:1 stm idmother using "${local_data}/temp_mother" // Merge the temporary dataset to original , m:1 because idmother can be zero for many + keep if _merge == 1 | _merge == 3 + drop _merge +end +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/input_processing/labour_supply/do-files/ADO/add_partner_variables.ado b/input_processing/labour_supply/do-files/ADO/add_partner_variables.ado new file mode 100644 index 0000000..60dfdbd --- /dev/null +++ b/input_processing/labour_supply/do-files/ADO/add_partner_variables.ado @@ -0,0 +1,29 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//PROGRAM TO ATTACH PARTNER VARIABLES TO THE RESPONDENT // +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +program define add_partner_variables + args partner_vars //assign arguments to local macros + + preserve // Preserve the original dataset + keep idperson `partner_vars' + rename idperson idpartner + + tokenize `partner_vars' // Split partner_vars into a list and store each resulting token in a numbered local macro. + while "`1'" != "" { // Loop over each variable and rename + capture confirm variable `1' // Check if the variable exists in the dataset + if !_rc { + rename `1' partner_`1' + } + macro shift //process each token in a loop + } + sort idpartner + //sum partner_* + save "${local_data}/temp_partner", replace // Save the modified dataset to a temporary file + restore // Restore the original dataset + + sort idpartner + merge m:1 idpartner using "${local_data}/temp_partner" // Merge the temporary dataset to original , m:1 because idpartner can be zero for many + keep if _merge == 1 | _merge == 3 + drop _merge +end +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/input_processing/labour_supply/do-files/ADO/add_partner_variables2.ado b/input_processing/labour_supply/do-files/ADO/add_partner_variables2.ado new file mode 100644 index 0000000..24e1f1c --- /dev/null +++ b/input_processing/labour_supply/do-files/ADO/add_partner_variables2.ado @@ -0,0 +1,29 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//PROGRAM TO ATTACH PARTNER VARIABLES TO THE RESPONDENT // +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +program define add_partner_variables2 + args partner_vars //assign arguments to local macros + + preserve // Preserve the original dataset + keep stm idperson `partner_vars' + rename idperson idpartner + + tokenize `partner_vars' // Split partner_vars into a list and store each resulting token in a numbered local macro. + while "`1'" != "" { // Loop over each variable and rename + capture confirm variable `1' // Check if the variable exists in the dataset + if !_rc { + rename `1' partner_`1' + } + macro shift //process each token in a loop + } + sort stm idpartner + //sum partner_* + save "${local_data}/temp_partner", replace // Save the modified dataset to a temporary file + restore // Restore the original dataset + + sort stm idpartner + merge m:1 stm idpartner using "${local_data}/temp_partner" // Merge the temporary dataset to original , m:1 because idpartner can be zero for many + keep if _merge == 1 | _merge == 3 + drop _merge +end +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/input_processing/labour_supply/do-files/PL master-elast.do b/input_processing/labour_supply/do-files/PL master-elast.do new file mode 100644 index 0000000..e4fe246 --- /dev/null +++ b/input_processing/labour_supply/do-files/PL master-elast.do @@ -0,0 +1,578 @@ +************************************************************************** +* Project: ESPON +* EU SILC (PL_2019_b3) +* Master file using std model plus single adult chidren (split) hhs for Poland +* +* Author: Zhechun He, Daria Popova +* Credit: Matteo Richiardi, Francesco Figari +* Latest revision: Daria Popova +* Date revised: 20 March 2026 +************************************************************************ +//note: "_indep" means singles are without partner, "_dep" means singles are not real singles, but live with non-flexible partner +//note: wage1:predicted wage for everyone. wage2:predicted wage for non-workers only. In the ls estimation, only wage1 is used. +************************************************************************ + + +clear all +set more off +set type double +set maxvar 30000 +set matsize 1000 +//version 14 + +/*Save add_partner_variables.ado add_mother_variables.ado and add_father_variables.ado in your ADO directory*/ + +*directories +global path "D:\Dasha\ESSEX\_SimPaths\_SimPaths_EU\PL\labour_supply" +global do_files "${path}\do-files" +global do_files_std "${path}\do-files\std singles and couples data preparation" +global do_files_adult_ch "${path}\do-files\adult children data preparation" +global do_files_specifications "${path}\do-files\model specifications" + + +global local_data "${path}\data" //folder to store data produced +global log "${path}\log" + +global results_wi "${path}\results\wage imputation" //folder to store wage imputation results and graphs +global results "${path}\results" //folder to store LS results + +global summary_table "${path}\results\summary_table" //folder to store general summary tables for all models + + +********************************************************************************************** + +global em_models "${path}/EUROMOD_RELEASES_I6.39+" //folder with the input, output etc. EUROMOD folders +global em_exe "C:\Program Files\EUROMOD\Executable\EM_ExecutableCaller.exe" //executable for EUROMOD + +global em_original "${em_models}\Input\Original" //EUROMOD original data folder + +global em_input "${em_models}\Input\" //EUROMOD input folder +global em_output "${em_models}\Output\" //EUROMOD output folder + +global file_input = "PL_2019_b3" +global file_output="pl_2018_std" //here output file is 2018 because 2018 system will be used with the 2019 data (2018 earnings) +global policy_year ="PL_2018" + +global impmethod "1" //predicted wages for everyone +*global impmethod "2" //predicted wages for non-working, observed wages for working + +*======================================================================= +* Globals used in Simpaths + +global age_seek_employment 16 + +global age_force_retire 75 + +global max_lhw 126 //ensure lhw is not above weekly maximum of 168 minus 6*7 hours of sleep + +global age_max_dep_child 17 + +/*----------------------------------------------------------------------------------------------- +* HOURS DISCRETISATION – POLAND 2018 +-----------------------------------------------------------------------------------------------*/ +global n_choices 4 // 1 non-work + 3 work brackets +global n_workchoices = $n_choices - 1 // work choices only + + +* Female +global min_hours_1_0 = 1 // [1,39] +global min_hours_2_0 = 40 // [40] +global min_hours_3_0 = 41 // [41,+∞) + +* Male +global min_hours_1_1 = 1 // [1,39] +global min_hours_2_1 = 40 // [40] +global min_hours_3_1 = 41 // [41,+∞) + +*======================================================================= + +* Set Excel file + +* Info sheet + +putexcel set "$results/reg_labourSupplyUtility_PL", sheet("Info") replace +putexcel A1 = ("Description:") +putexcel B1 = ("Regression estimates used by the labour supply process for the following subsamples:") +putexcel B2 = ("1- Single females") +putexcel B3 = ("2- Single males") +putexcel B4 = ("3- Couples with two labour flexible") +putexcel B5 = ("4- Singles with dependent, females") +putexcel B6 = ("5- Singles with dependent, males") +putexcel B7 = ("6- Single adult children, females") +putexcel B8 = ("7- Single adult children, males") + +putexcel A10 = ("Notes:") +putexcel B10 = ("Added filter for single adult children to ensure consistency with sample used in simulation") +putexcel B11 = ("Subtracted 6 hours of sleep per day from lhw") + +putexcel A15 =("Last update: 20 March 2026 by Daria Popova") + +***************************************************************************************************************************** +* Set Excel file for wages +* Info sheet - first stage +putexcel set "$results_wi/reg_employment_selection", sheet("Info") replace +putexcel A1 = "Description:" +putexcel B1 = "This file contains regression estimates from the first stage of the Heckman selection model used to estimates wages." +putexcel A2 = "Authors: Daria Popova" +putexcel A3 = "Last edit: 9 April 2026" + +putexcel A5 = "Process:", bold +putexcel B5 = "Description:", bold +putexcel A6 = "W1-sel" +putexcel B6 = "First stage Heckman selection estimates for women (low wages)" +putexcel A7 = "M1-sel" +putexcel B7 = "First stage Heckman selection estimates for men (low wages)" +putexcel A8 = "W2-sel" +putexcel B8 = "First stage Heckman selection estimates for women (normal wages)" +putexcel A9 = "M2-sel" +putexcel B9 = "First stage Heckman selection estimates for men (normal wages)" + +putexcel A11 = "Notes:", bold +putexcel B11 = "Estimated on EUROMOD input data PL_2019_b3" +putexcel B12 = "Two-step Heckman command is used which does not permit weights" + +* Info sheet - second stage +putexcel set "$results_wi/reg_wages", sheet("Info") replace +putexcel A1 = "Description:" +putexcel B1 = "This file contains regression estimates used to calculate potential wages for males and females in the simulation." +putexcel A2 = "Authors: Daria Popova" +putexcel A3 = "Last edit: 9 April 2026" + +putexcel A5 = "Process:", bold +putexcel B5 = "Description:", bold +putexcel A6 = "W1" +putexcel B6 = "Second stage Heckman selection estimates for women (low wages)" +putexcel A7 = "M1" +putexcel B7 = "Second stage Heckman selection estimates for men (low wages)" +putexcel A8 = "W2" +putexcel B8 = "Second stage Heckman selection estimates for women (normal wages)" +putexcel A9 = "M2" +putexcel B9 = "Second stage Heckman selection estimates for men (normal wages)" + + +putexcel A11 = "Notes:", bold +putexcel B11 = "Estimated on EUROMOD input data PL_2019_b3" +putexcel B12 = "Two-step Heckman command is used which does not permit weights" + + + +*======================================================================= +* std singles and couples +*======================================================================= + +//-input and output data in EM +do "$do_files_std\1-input and output data-std model.do" //for std singles and couples, get wage estimates, impute wages in two ways, run EM + +//-target samples +do "$do_files_std\2a-singles sample-std model.do" //get sample for single and generate the vbls needed for ls (std singles) + +do "$do_files_std\2b-couples sample-std model.do" //get sample for couple and generate the vbls needed for ls (std couples) + +//-run EM in preparation for computing elasticity +do "$do_files_std\3a-EM single wage elasticity-std model.do" //run EM to get the ils_dispy for sample of singles resulting from a 10% increase in gross wage (std singles) + +do "$do_files_std\3b-EM couple wage elasticity-std model.do" //run EM to get the ils_dispy for sample of couples resulting from a 10% increase in gross wage (std couples) + + +*======================================================================= +* single adult children (split hhs) +*======================================================================= + +//-input and output data in EM +do "$do_files_adult_ch\1-input and output data-dropped sample.do" //for adult children, split households, run EM + +//-target samples +do "$do_files_adult_ch\2-singles sample-dropped sample.do" //get sample for single and generate the vbls needed for ls (single adult children) + +//-run EM in preparation for computing elasticity +do "$do_files_adult_ch\3-EM single wage elasticity-adult_ch.do" //run EM to get the ils_dispy for sample of singles resulting from a 10% increase in gross wage + + +/* +*======================================================================= +* LS models -clogit - baseline specification +*======================================================================= +*These globals have to be updated for the version of the LS model +global results_ls "${path}/results\LS_v1" //folder to store LS results - baseline model with predicted wages for everyone + +global sheet "LS_v1" + +do "$do_files_specifications\4a-singles_indep_elast-std model.do" //predictors: hhcon_100 hhcon2_10000 leisure leisure2 lei_hhcon_100 fixed_cost + +do "$do_files_specifications\4b-singles_dep_elast-std model.do" //predictors: hhcon_100 hhcon2_10000 leisure leisure2 lei_hhcon_100 fixc_dgn + +do "$do_files_specifications\4c-couples elast-std model.do" //predictors: hhcon_100 hhcon2_10000 leisure sp_leisure leisure2 sp_leisure2 lei_sp_lei lei_hhcon_100 sp_lei_hhcon_100 fixed_cost sp_fixed_cost + +do "$do_files_specifications\4d-singles_indep_elast-adult_ch.do" //estimate ls for singles and compute MU, elasticity (adult children-indep) + + +*======================================================================= +* LS models -clogit - baseline specification +*======================================================================= +*These globals have to be updated for the version of the LS model +global results_ls "${path}/results\LS_v2" //folder to store LS results - baseline model with number of months in employment + +global sheet "LS_v2" + +do "$do_files_specifications\4a-singles_indep_elast-std model - v2.do" + +do "$do_files_specifications\4b-singles_dep_elast-std model - v2.do" + +do "$do_files_specifications\4c-couples elast-std model - v2.do" + +do "$do_files_specifications\4d-singles_indep_elast-adult_ch - v2.do" + + +*======================================================================= +* LS models -clogit - baseline specification +*======================================================================= +*These globals have to be updated for the version of the LS model +global results_ls "${path}/results\LS_v3" //folder to store LS results - baseline model with predicted wages for everyone and regional dummies + +global sheet "LS_v3" + +do "$do_files_specifications\4a-singles_indep_elast-std model - v3.do" + +do "$do_files_specifications\4b-singles_dep_elast-std model - v3.do" + +do "$do_files_specifications\4c-couples elast-std model - v3.do" + +do "$do_files_specifications\4d-singles_indep_elast-adult_ch - v3.do" + + +*======================================================================= +* LS models -clogit - baseline specification +*======================================================================= +*These globals have to be updated for the version of the LS model +global results_ls "${path}/results\LS_v4" //folder to store LS results - baseline model with predicted wages for everyone and higher education dummy + +global sheet "LS_v4" + +do "$do_files_specifications\4a-singles_indep_elast-std model - v4.do" + +do "$do_files_specifications\4b-singles_dep_elast-std model - v4.do" + +do "$do_files_specifications\4c-couples elast-std model - v4.do" + +do "$do_files_specifications\4d-singles_indep_elast-adult_ch - v4.do" + + +*======================================================================= +* LS models -clogit - baseline specification +*======================================================================= +*These globals have to be updated for the version of the LS model +global results_ls "${path}/results\LS_v5" //folder to store LS results - baseline model with interactions of age with leisure + +global sheet "LS_v5" + +do "$do_files_specifications\4a-singles_indep_elast-std model - v5.do" + +do "$do_files_specifications\4b-singles_dep_elast-std model - v5.do" + +do "$do_files_specifications\4c-couples elast-std model - v5.do" + +do "$do_files_specifications\4d-singles_indep_elast-adult_ch - v5.do" + + +*======================================================================= +* LS models -clogit - baseline specification +*======================================================================= +*These globals have to be updated for the version of the LS model +global results_ls "${path}/results\LS_v6" //folder to store LS results - baseline model with interactions of age with income + +global sheet "LS_v6" + +do "$do_files_specifications\4a-singles_indep_elast-std model - v6.do" + +do "$do_files_specifications\4b-singles_dep_elast-std model - v6.do" + +do "$do_files_specifications\4c-couples elast-std model - v6.do" + +do "$do_files_specifications\4d-singles_indep_elast-adult_ch - v6.do" + + + +*======================================================================= +* LS models -clogit - baseline specification +*======================================================================= +*These globals have to be updated for the version of the LS model +global results_ls "${path}/results\LS_v7" //folder to store LS results - baseline model with interactions of children with leisure + +global sheet "LS_v7" + +do "$do_files_specifications\4a-singles_indep_elast-std model - v7.do" + +do "$do_files_specifications\4b-singles_dep_elast-std model - v7.do" + +do "$do_files_specifications\4c-couples elast-std model - v7.do" + +do "$do_files_specifications\4d-singles_indep_elast-adult_ch - v7.do" + + + +*======================================================================= +* LS models -clogit - baseline specification +*======================================================================= +*These globals have to be updated for the version of the LS model +global results_ls "${path}/results\LS_v8" //folder to store LS results - baseline model with interactions of children with income + +global sheet "LS_v8" + +do "$do_files_specifications\4a-singles_indep_elast-std model - v8.do" + +do "$do_files_specifications\4b-singles_dep_elast-std model - v8.do" + +do "$do_files_specifications\4c-couples elast-std model - v8.do" + +do "$do_files_specifications\4d-singles_indep_elast-adult_ch - v8.do" + + + +*======================================================================= +* LS models -clogit - baseline specification +*======================================================================= +*These globals have to be updated for the version of the LS model +global results_ls "${path}/results\LS_v9" //folder to store LS results - baseline model with interactions of age and children with leisure + +global sheet "LS_v9" + +do "$do_files_specifications\4a-singles_indep_elast-std model - v9.do" + +do "$do_files_specifications\4b-singles_dep_elast-std model - v9.do" + +do "$do_files_specifications\4c-couples elast-std model - v9.do" + +do "$do_files_specifications\4d-singles_indep_elast-adult_ch - v9.do" + + +*======================================================================= +* LS models -clogit - baseline specification +*======================================================================= +*These globals have to be updated for the version of the LS model +global results_ls "${path}/results\LS_v10" //folder to store LS results - baseline model with interactions of age and children with leisure + education dummies + +global sheet "LS_v10" + +do "$do_files_specifications\4a-singles_indep_elast-std model - v10.do" + +do "$do_files_specifications\4b-singles_dep_elast-std model - v10.do" + +do "$do_files_specifications\4c-couples elast-std model - v10.do" + +do "$do_files_specifications\4d-singles_indep_elast-adult_ch - v10.do" + + +*======================================================================= +* LS models -clogit - baseline specification +*======================================================================= +*These globals have to be updated for the version of the LS model +global results_ls "${path}/results\LS_v11" //folder to store LS results - baseline model with interactions of age and children with leisure + liwwh + +global sheet "LS_v11" + +do "$do_files_specifications\4a-singles_indep_elast-std model - v11.do" + +do "$do_files_specifications\4b-singles_dep_elast-std model - v11.do" + +do "$do_files_specifications\4c-couples elast-std model - v11.do" + +do "$do_files_specifications\4d-singles_indep_elast-adult_ch - v11.do" + + +*======================================================================= +* LS models -clogit - baseline specification +*======================================================================= +*These globals have to be updated for the version of the LS model +global results_ls "${path}/results\LS_v12" //folder to store LS results - baseline model with interactions of age, children and education dummies with leisure + +global sheet "LS_v12" + + +do "$do_files_specifications\4a-singles_indep_elast-std model - v12.do" + +do "$do_files_specifications\4b-singles_dep_elast-std model - v12.do" + +do "$do_files_specifications\4c-couples elast-std model - v12.do" + +do "$do_files_specifications\4d-singles_indep_elast-adult_ch - v12.do" + + +*======================================================================= +* LS models -clogit - baseline specification +*======================================================================= +*These globals have to be updated for the version of the LS model +global results_ls "${path}/results\LS_v13" //folder to store LS results - baseline model with house ownership dummies + +global sheet "LS_v13" + +do "$do_files_specifications\4a-singles_indep_elast-std model - v13.do" + +do "$do_files_specifications\4b-singles_dep_elast-std model - v13.do" + +do "$do_files_specifications\4c-couples elast-std model - v13.do" + +do "$do_files_specifications\4d-singles_indep_elast-adult_ch - v13.do" + + +*======================================================================= +* LS models -clogit - baseline specification +*======================================================================= +*These globals have to be updated for the version of the LS model +global results_ls "${path}/results\LS_v14" //folder to store LS results - baseline model with self-rated health dummies + +global sheet "LS_v14" + +do "$do_files_specifications\4a-singles_indep_elast-std model - v14.do" + +do "$do_files_specifications\4b-singles_dep_elast-std model - v14.do" + +do "$do_files_specifications\4c-couples elast-std model - v14.do" + +do "$do_files_specifications\4d-singles_indep_elast-adult_ch - v14.do" + + +*======================================================================= +* LS models -clogit - baseline specification without fixed cost +*======================================================================= +*These globals have to be updated for the version of the LS model +global results_ls "${path}/results\LS_v15" //folder to store LS results - baseline model without fixed costs +global sheet "LS_v15" + +do "$do_files_specifications\4a-singles_indep_elast-std model - v15.do" + +do "$do_files_specifications\4b-singles_dep_elast-std model - v15.do" + +do "$do_files_specifications\4c-couples elast-std model - v15.do" + +do "$do_files_specifications\4d-singles_indep_elast-adult_ch - v15.do" + + +*======================================================================= +* LS models -clogit - baseline specification without fixed cost +*======================================================================= +*These globals have to be updated for the version of the LS model +global results_ls "${path}/results\LS_v16" //folder to store LS results - baseline model without fixed costs + liwwh +global sheet "LS_v16" + +do "$do_files_specifications\4a-singles_indep_elast-std model - v16.do" + +do "$do_files_specifications\4b-singles_dep_elast-std model - v16.do" + +do "$do_files_specifications\4c-couples elast-std model - v16.do" + +do "$do_files_specifications\4d-singles_indep_elast-adult_ch - v16.do" + + +*======================================================================= +* LS models -clogit - baseline specification without fixed cost +*======================================================================= +*These globals have to be updated for the version of the LS model +global results_ls "${path}/results\LS_v17" //folder to store LS results - baseline model without fixed costs + 40 hours dummy +global sheet "LS_v17" + +do "$do_files_specifications\4a-singles_indep_elast-std model - v17.do" + +do "$do_files_specifications\4b-singles_dep_elast-std model - v17.do" + +do "$do_files_specifications\4c-couples elast-std model - v17.do" + +do "$do_files_specifications\4d-singles_indep_elast-adult_ch - v17.do" + + +*======================================================================= +* LS models -clogit - baseline specification without fixed cost +*======================================================================= +*These globals have to be updated for the version of the LS model +global results_ls "${path}/results\LS_v18" //folder to store LS results - baseline model without fixed costs + 40plus hours dummy +global sheet "LS_v18" + +do "$do_files_specifications\4a-singles_indep_elast-std model - v18.do" + +do "$do_files_specifications\4b-singles_dep_elast-std model - v18.do" + +do "$do_files_specifications\4c-couples elast-std model - v18.do" + +do "$do_files_specifications\4d-singles_indep_elast-adult_ch - v18.do" + + +*======================================================================= +* LS models -clogit - baseline specification without fixed cost +*======================================================================= +*These globals have to be updated for the version of the LS model +global results_ls "${path}/results\LS_v19" //folder to store LS results - baseline model without fixed costs + 40plus hours dummy + liwwh +global sheet "LS_v19" + +do "$do_files_specifications\4a-singles_indep_elast-std model - v19.do" + +do "$do_files_specifications\4b-singles_dep_elast-std model - v19.do" + +do "$do_files_specifications\4c-couples elast-std model - v19.do" + +do "$do_files_specifications\4d-singles_indep_elast-adult_ch - v19.do" + + +*======================================================================= +* LS models -clogit - baseline specification without fixed cost +*======================================================================= +*These globals have to be updated for the version of the LS model +global results_ls "${path}/results\LS_v20" //folder to store LS results - baseline model without fixed costs + 40plus hours dummy + liwwh & liwwh squared +global sheet "LS_v20" + +do "$do_files_specifications\4a-singles_indep_elast-std model - v20.do" + +do "$do_files_specifications\4b-singles_dep_elast-std model - v20.do" + +do "$do_files_specifications\4c-couples elast-std model - v20.do" + +do "$do_files_specifications\4d-singles_indep_elast-adult_ch - v20.do" + + +*======================================================================= +* LS models -clogit - baseline specification without fixed cost +*======================================================================= +*These globals have to be updated for the version of the LS model +global results_ls "${path}/results\LS_v21" //folder to store LS results - baseline model without fixed costs + 40plus hours dummy + ln_liwwh +global sheet "LS_v21" + +do "$do_files_specifications\4a-singles_indep_elast-std model - v21.do" + +do "$do_files_specifications\4b-singles_dep_elast-std model - v21.do" + +do "$do_files_specifications\4c-couples elast-std model - v21.do" + +do "$do_files_specifications\4d-singles_indep_elast-adult_ch - v21.do" + + +*======================================================================= +* LS models -clogit - baseline specification without fixed cost +*======================================================================= +*These globals have to be updated for the version of the LS model +global results_ls "${path}/results\LS_v22" //folder to store LS results - baseline model without fixed costs + 40plus hours dummy + liwwh dummies +global sheet "LS_v22" + +do "$do_files_specifications\4a-singles_indep_elast-std model - v22.do" + +do "$do_files_specifications\4b-singles_dep_elast-std model - v22.do" + +do "$do_files_specifications\4c-couples elast-std model - v22.do" + +do "$do_files_specifications\4d-singles_indep_elast-adult_ch - v22.do" +*/ + +*======================================================================= +* LS models -clogit - baseline specification without fixed cost - final version to be used in the model +*======================================================================= +*These globals have to be updated for the version of the LS model +global results_ls "${path}/results\LS_final" //folder to store LS results - v20: baseline model without fixed costs + 40plus hours dummy + liwwh & liwwh squared +global sheet "LS_final" + +do "$do_files_specifications\4a-singles_indep_elast-std model - final.do" + +do "$do_files_specifications\4b-singles_dep_elast-std model - final.do" + +do "$do_files_specifications\4c-couples elast-std model - final.do" + +do "$do_files_specifications\4d-singles_indep_elast-adult_ch - final.do" + + + diff --git a/input_processing/labour_supply/do-files/add_original_SILC_vars.do b/input_processing/labour_supply/do-files/add_original_SILC_vars.do new file mode 100644 index 0000000..2b17b47 --- /dev/null +++ b/input_processing/labour_supply/do-files/add_original_SILC_vars.do @@ -0,0 +1,61 @@ +*************************************************************************************** +* PROJECT: ESPON: construct a cross-sectional panel dataset deom EU-SILC database +* ************************************************************************************** +version 14 +clear +set logtype smcl +set more off +set mem 200m +set type double + +*open original SILC dataset in Stata +insheet using "D:\Dasha\ESSEX\_SimPaths\_SimPaths_EU\PL\labour_supply\data\EU-SILC-2019-orig\UDB_cPL19P.csv", clear +//save "D:\Dasha\ESSEX\ESPON 2024\PL\labour_supply\data\UDB_cPL19P.dta", replace + +/*add additional variables from original EU-SILC */ +//use "D:\Dasha\ESSEX\ESPON 2024\PL\labour_supply\data\UDB_cPL19P.dta", clear +/*rename idperson_e idperson +rename idhh_e idhh +rename dgn_e dgn +rename dag_e dag +rename drgn1_e drgn1 +*/ +gen double idhh = px030 +gen double idperson = pb030 +qui count +display in y "P-FILE - number of observations: " r(N) +sort idhh idperson + +/**********************************Health status*******************************/ +/*fre PH010 +PH010 -- PH010 + +Freq. Percent Valid Cum. + +Valid +1 1543 10.28 11.92 11.92 +2 4769 31.79 36.84 48.76 +3 4503 30.01 34.79 83.55 +4 1582 10.54 12.22 95.77 +5 547 3.65 4.23 100.00 +Total 12944 86.28 100.00 +Missing . 2059 13.72 +Total 15003 100.00 + +code negative values to missing, reverse code so 5 = excellent and higher number means better health +*/ + +recode ph010 (5 = 1 "Poor") /// + (4 = 2 "Fair") /// + (3 = 3 "Good") /// + (2 = 4 "Very good") /// + (1 = 5 "Excellent") /// + , into(dhe) +la var dhe "Health status" +fre dhe + +keep idperson idhh dhe +sort idhh idperson + +save "D:\Dasha\ESSEX\_SimPaths\_SimPaths_EU\PL\labour_supply\data\temp_dhe.dta", replace + diff --git a/input_processing/labour_supply/do-files/adult children data preparation/1-input and output data-dropped sample.do b/input_processing/labour_supply/do-files/adult children data preparation/1-input and output data-dropped sample.do new file mode 100644 index 0000000..db06a90 --- /dev/null +++ b/input_processing/labour_supply/do-files/adult children data preparation/1-input and output data-dropped sample.do @@ -0,0 +1,828 @@ +************************************************************************** +* Poland EM data (PL_2019_b3.txt data) +* for adult children, split households, run EM +************************************************************************ +/*This code extracts adult children who were excluded from the standard labour supply sample +and prepares them as a separate estimation group */ + +global file_log="input_output_data-adult children" + +global n_choices = 4 // 4 choices: no work, plus 3 hours brackets. +global n_workchoices = $n_choices - 1 // 3 choices with positive supply of hours, 1 choice with 0 hours. + +*HU 2018 hours discretisation +*female +global min_hours_1_0 = 1 // min hrs for [1,39] +global min_hours_2_0 = 40 // min hrs for [40,49] +global min_hours_3_0 = 41 // min hrs for [41,+∞) + +*male +global min_hours_1_1 = 1 // min hrs for [1,39] +global min_hours_2_1 = 40 // min hrs for [40,49] +global min_hours_3_1 = 41 // min hrs for [41,+∞) + + +cd "$local_data" +pwd + +*version 13 +capture log close +log using "$file_log", replace + +clear all +set seed 1 //same seed gives same results + + +use beforeReshape.dta, clear + +keep temp_idorigperson2 +rename temp_idorigperson2 idperson +//try changing "double" to "long" for idperson +gen long idperson2=idperson +drop idperson +rename idperson2 idperson + +/*afterheckman.dta contains everyone remaining after all the sample trimming for the standard model. +We merge adult children (beforeReshape) with afterheckman. +We keep only the individuals who appear in afterheckman but NOT in beforeReshape. +These are exactly the individuals: +… who were dropped from your standard LS model +… but still exist in the overall survey */ +merge 1:1 idperson using afterheckman +assert _merge!=1 //beforeReshape sample is a subsample of afterheckman +keep if _merge==2 //keep only those obs dropped from the std model +drop _merge + +duplicates report idperson //count how many unique individuals there are +//21041 obs + +//fre temp_adultchildflag + + +*add the hh split code here +*======================================================================= +* Household composition +*======================================================================= +gen long temp_before_idperson=idperson //save id's before the artificial hh split. +gen long temp_before_idpartner=idpartner +gen long temp_before_idhh=idhh +gen long temp_before_idmother=idmother +gen long temp_before_idfather=idfather + format temp_before_id* %20.0g + format id* %20.0g + format temp_before_id* %20.0g + format id* %20.0g +assert idperson==idorigperson //this is not the same as UK +keep if idperson == idhh * 100 + mod(idorigperson,idhh*100) //0 obs dropped + *------------------------------------------------------------------------------------------------------ + * "Adjust" households: each household will only be comprised of one or two partners (male and female), and their children + * dgn: 0 (female); 1 (male) + * Same-sex partners are temporarily assigned “virtual” genders so that EUROMOD can treat the pair as a male–female couple. + *------------------------------------------------------------------------------------------------------ + // count same-sex partner + add_partner_variables "dgn" + tab dgn partner_dgn, m + + // assign "virtual" sex to same-sex partners (first record: male; second record: female) + + * female senior partner turned into "virtual" male + gen dgn2 = 1 if dgn == 0 & partner_dgn == 0 & idperson < idpartner + add_mother_variables "dgn2" + replace dgn = 1 if dgn2 == 1 + replace idfather = idmother if mother_dgn2 == 1 // these are the mothers who have been turned into "virtual" males + replace idmother = 0 if mother_dgn2 == 1 + drop mother_dgn2 + drop dgn2 + + * male junior partner turned into "virtual" female + gen dgn2 = 0 if dgn == 1 & partner_dgn == 1 & idperson > idpartner + add_father_variables "dgn2" + replace dgn = dgn2 if dgn2 == 0 + replace idmother = idfather if father_dgn2 == 0 // these are the fathers who have been turned into "virtual" females + replace idfather = 0 if father_dgn2 == 0 + drop father_dgn2 + drop dgn2 + + drop partner_dgn + + // check no more same-sex partners + add_partner_variables "dgn" + assert dgn != partner_dgn if dgn!=. //added "if dgn!=." + drop if dgn==. //added + drop partner_dgn + + // check fathers are males and mothers are females + add_father_variables "dgn" + add_mother_variables "dgn" + assert father_dgn != 0 + assert mother_dgn != 1 + drop father_dgn mother_dgn + + // check that parents' id are within the household + gen long idhh_father = floor(idfather/100) + gen long idhh_mother = floor(idmother/100) + assert idhh_father == idhh if idhh_father != 0 + assert idhh_mother == idhh if idhh_mother != 0 + drop idhh_father idhh_mother + + // assert rule for creating idperson + drop if idhh==. //added + //assert idperson == idhh * 100 + idorigperson //this rule is for UK + assert idperson == idhh * 100 + mod(idorigperson,idhh*100) + + scalar lambda = 10000000 + gen long new_idhh = idhh + gen long new_idperson = idperson + gen long new_idpartner = idpartner + gen long new_idmother = idmother + gen long new_idfather = idfather + format id* new_* %12.0g + + // single individuals aged 16+ (anyone aged >= 16 whose idpartner=0 forms a new household on his/her own) + gen byte d_single = (dag >= 16 & idpartner == 0 ) + replace new_idhh = lambda + idperson if d_single //new_idhh created for those with idpartner=0 + replace new_idperson = new_idhh * 100 + idorigperson if d_single //corresponding idperson for those with idpartner=0 + replace new_idmother = 0 if d_single //because they are 16+ + replace new_idfather = 0 if d_single //because they are 16+ + *Note that new_idpartner does not need to be changed for singles because they are equal to the old idpartner which is 0. + drop d_single + + // males in couples aged 16+ ... (anyone aged >= 16 whose idpartner>0 forms a new household with his/her partner) + gen byte d_malepartner = (dag >= 16 & idpartner > 0 & dgn == 1) + replace new_idhh = lambda + idperson if d_malepartner //new_idhh created for male partners + replace new_idperson = new_idhh*100+idorigperson if d_malepartner //corresponding new_idperson for male partners + * new_idpartner will be imputed below (female id have not been reset yet) + replace new_idmother = 0 if d_malepartner //because they are 16+ + replace new_idfather = 0 if d_malepartner //because they are 16+ + + // ... and their female partners + add_partner_variables "new_idhh new_idperson" // first round: impute the new ids of the male partners to their female partners + gen byte d_femalepartner = (dag >= 16 & idpartner > 0 & dgn == 0) + replace new_idhh = partner_new_idhh if d_femalepartner //new_idhh=new_idhh of their partners + replace new_idperson = new_idhh * 100 + idorigperson if d_femalepartner //corresponding new_idperson for female partners + replace new_idpartner = partner_new_idperson if d_femalepartner + replace new_idmother = 0 if d_femalepartner //because they are 16+ + replace new_idfather = 0 if d_femalepartner //because they are 16+ + drop d_femalepartner + drop partner_new* + + // now that female partners have their new id, this can be imputed to their male partners + add_partner_variables "new_idperson" // second round: impute the new ids of the female partners to their male partners + replace new_idpartner = partner_new_idperson if d_malepartner + drop d_malepartner + drop partner_new* + + **Note: Up to this point, everyone aged >=16 (whether have a partner or not) has + **been assigned a new_idhh, new_idperson,new_idpartner, new_idmother, new_idfather. + + // add dependent children (<16) to their father's hh if no mother + add_father_variables "new_idhh new_idperson" + gen byte d_childfather = (dag < 16 & idfather > 0 & idmother == 0) //children who have a father but no mother + replace new_idhh = father_new_idhh if d_childfather //assgin new_idhh of their father to them + replace new_idperson = new_idhh * 100 + idorigperson if d_childfather //corresponding new_idperson for these children + replace new_idfather = father_new_idperson if d_childfather //corresponding new_idfather + drop d_childfather + + // add dependent children (<16) to their mother's hh, if any + add_mother_variables "new_idhh new_idperson" + gen byte d_childmother = (dag < 16 & idmother > 0) //children who have a mother (whehter have a father or not) + replace new_idhh = mother_new_idhh if d_childmother //assgin new_idhh of their mother to them (overwritten for those children have both parents) + replace new_idperson = new_idhh * 100 + idorigperson if d_childmother + replace new_idfather = father_new_idperson if d_childmother + replace new_idfather = 0 if new_idfather == . // children with no father have missing father_new_idperson + replace new_idmother = mother_new_idperson if d_childmother //corresponding new_idmother + drop d_childmother + + **Note: Up to this point, everyone aged <16 has + **been assigned a new_idhh, new_idperson,new_idpartner, new_idmother, new_idfather. + + // repeat for children of under-age fathers (eg. idhh == 661) + drop father_new* + add_father_variables "new_idhh new_idperson" + gen byte d_childfather = (dag < 16 & idfather > 0 & idmother == 0) + replace new_idhh = father_new_idhh if d_childfather + replace new_idperson = new_idhh * 100 + idorigperson if d_childfather + replace new_idfather = father_new_idperson if d_childfather + drop d_childfather + + // repeat for children of under-age mothers (eg. idhh == 661) + drop mother_new* + add_mother_variables "new_idhh new_idperson" + gen byte d_childmother = (dag < 16 & idmother > 0) + replace new_idhh = mother_new_idhh if d_childmother + replace new_idperson = new_idhh * 100 + idorigperson if d_childmother + replace new_idfather = father_new_idperson if d_childmother + replace new_idfather = 0 if new_idfather == . // children with no father have missing father_new_idperson + replace new_idmother = mother_new_idperson if d_childmother + drop d_childmother + + drop father_new* mother_new* + + // drop dependent children (<16) with no mother nor father + drop if dag < 16 & idmother == 0 & idfather == 0 //(15 observations deleted) + + + replace idhh = new_idhh + replace idperson = new_idperson + replace idpartner = new_idpartner + replace idpartner = 0 if idpartner == . + replace idmother = new_idmother + replace idfather = new_idfather + drop new_* + drop if idperson==. //added + duplicates report idperson //no duplicate + + assert idfather>0 | idmother>0 if dag<16 + assert idfather==0 if dag>16 + + +/*------------------------------------------------------------CHECK below +This code sorts households into: +Singles households +→ exactly one flexible adult (lone parent or single adult) +Couples households +→ exactly two flexible adults (couple) +Households that should be dropped +→ households with no flexible adults (students, children, non-participants) +It also performs consistency checks to ensure no impossible households exist (e.g. households with both singles and couples, or >2 flexible workers). +*/ + +bysort idhh: egen temp_with_singles=total(temp_singles), missing //missing as 0 +replace temp_with_singles=(temp_with_singles>0) //dummy of at least one family member is "singles" + +bysort idhh: egen temp_with_couples=total(temp_couples), missing +replace temp_with_couples=(temp_with_couples>0) //dummy of at least one family member is "couples" +count if temp_singles==1 & temp_n_ch>0 //332 obs + +//check whether a not flexible individual can have temp_with_couples=1 and temp_with_singles=1 at the same time : no such cases +su dag if temp_with_singles==1 &temp_with_couples==1 &temp_not_flexible==1 //they are <16 and either pre-school or student +tab les if temp_with_singles==1 &temp_with_couples==1 &temp_not_flexible==1 //they are <16 and either pre-school or student +*** +su temp_singles temp_couples temp_not_flexible if temp_with_singles==1 &temp_with_couples==1 //this shows singles, couples, and not flexible individuals can all live together + +count if temp_with_singles==1 &temp_with_couples==1 //0 obs + +//count if there are more than one flexible workers (lone parent+child aged between 16 and 18 and not student) in a "singles"' household +gen worker_count=(temp_not_flexible==0) +bysort idhh: egen number_workers_singleshh=total(worker_count) if temp_singles==1, missing +su number_workers_singleshh +count if number_workers_singleshh>1 & temp_singles==1 //0 obs +//duplicates report idhh if number_workers_singleshh>1 & temp_singles==1 + +//check there are no more than TWO flexible workers in a "COUPLES"' household +bysort idhh: egen number_workers_coupleshh=total(worker_count) if temp_couples==1, missing +su number_workers_couples +count if number_workers_coupleshh>2 & temp_couples==1 //0 obs +drop if number_workers_coupleshh>2 & temp_couples==1 //new in "using original hhs" +drop if number_workers_coupleshh<2 & temp_couples==1 //0 obs dropped +assert number_workers_coupleshh==2 if temp_couples==1 + +duplicates report idperson //count how many unique individuals there are + +count if temp_p_student //16 obs +//dropping +drop if temp_with_singles==1 &temp_with_couples==1 //0 obs dropped +duplicates report idperson //count how many unique individuals there are + +*Given the no. of hhs (lone parent+child aged between 16 and 18 and not student) is small, drop them +drop if number_workers_singleshh>1 & temp_singles==1 //0 obs dropped +duplicates report idperson //count how many unique individuals there are + +assert number_workers_singles==1 if temp_singles==1 +drop worker_count number_* //22/1/2021 +gen temp_alt_n=(temp_with_singles==1 & temp_with_couples==0) //dummy of individuals that should have n alternatives +gen temp_alt_nsq=(temp_with_couples==1) //dummy of individuals that should have n^2 alternatives +gen temp_drop=(temp_with_singles==0 & temp_with_couples==0) //dummy of individuals that can be dropped from EUROMOD input data because they are neither singles nor couples and do not live with singles or couples +assert temp_not_flexible==1 if temp_drop==1 //check that all individuals who will be dropped are not flexible +assert temp_alt_n+temp_alt_nsq+temp_drop==1 + +*======================================================================= +* Labour supply alternatives +*======================================================================= +drop if temp_drop==1 //to reduce the burden of EUROMOD +duplicates report idperson //count how many unique individuals there are + +* create columns with imputed alternatives (same for everyone who is labour supply flexible) +foreach gender in 0 1{ +local i = 0 +levelsof temp_lhw_dobs_`gender', local(levels) +foreach l in `r(levels)' { + gen byte temp_lhw_dobs_`gender'_`i' = `l' if temp_not_flexible==0 + local i = `i' + 1 +} //loop end of ls alternatives `i' +} //loop end of gender `gender' +sum temp_lhw_dobs_* + +/* +forvalues i = 1 (1) $n_workchoices{ + assert lhw != . + replace temp_bracket = `i' if lhw > $min_hours_`i' +} +*/ + +* choice set: generation of $n_choices^2 columns +// first index refers to male choice, second index refers to female choice +// note: couples (both partners flexible) have access to all $n_choices^2 options, +// note: Although "singles" have access only to $n_choices options, I replicate these $n_choices across all choices of their partners. +// note: not flexible individuals' all options =0 hrs +// Due to the way to construct fake id* to cheat EUROMOD, the treatment to "singles" and not flexible individuals is only for the purpose of linking with flexible people in the same hh +// to provide info for EUROMOD. +forvalues m=0/$n_workchoices { + forvalues f=0/$n_workchoices { + + capture drop lhw_`m'`f' + gen byte lhw_`m'`f' = . + replace lhw_`m'`f'=0 if temp_not_flexible==1 //both genders of not flexible individuals + // males + replace lhw_`m'`f' = temp_lhw_dobs_1_`m' if dgn == 1 & (temp_couples==1 |temp_singles==1) //male partner in flexible couples and male individuals in "singles" + + // females + replace lhw_`m'`f' = temp_lhw_dobs_0_`f' if dgn == 0 & (temp_couples==1 |temp_singles==1) //female partner in flexible couples and female individuals in "singles" + } +} + + +* choice conversion +// for flexible couples, flag for choice_`m'`f' is switched on only when the male partner chooses `m' and the female partner chooses `f' +// for second type of "singles", the inflexible partner always chooses 1st bracket (ie. 0 hours) +// for first type of "singles" (without a partner), we assume that their virtual partner chooses 1st bracket (ie. 0 hours). +// first index refers to male choice, second index refers to female choice + + add_partner_variables "temp_bracket_0 temp_bracket_1 dgn" + replace partner_temp_bracket_0 = 0 if idpartner>0 &partner_dgn==0 &(temp_p_student==1|temp_p_sick_dis==1|temp_p_workage==0) //second type of "singles"' partner must not work + replace partner_temp_bracket_1 = 0 if idpartner>0 &partner_dgn==1 &(temp_p_student==1|temp_p_sick_dis==1|temp_p_workage==0) //second type of "singles"' partner must not work + + +forvalues m=0/$n_workchoices { + forvalues f=0/$n_workchoices { + gen byte temp_choicehh_`m'`f' = . + // males + replace temp_choicehh_`m'`f' = (temp_bracket_1 == `m' & partner_temp_bracket_0 == `f') if dgn == 1 & temp_couples==1 //male partner in flexible couples + replace temp_choicehh_`m'`f' = (temp_bracket_1 == `m') if dgn == 1 & temp_singles==1 & `f' == 0 //male "singles" + // females + replace temp_choicehh_`m'`f' = (temp_bracket_0 == `f' & partner_temp_bracket_1 == `m') if dgn == 0 & temp_couples==1 //female partner in flexible couples + replace temp_choicehh_`m'`f' = (temp_bracket_0 == `f') if dgn == 0 & temp_singles==1 & `m' == 0 //female "singles" + } +} + + +drop partner_temp_bracket* + +*------------------------------------------------------------ +* Earnings +*------------------------------------------------------------ +cap drop yem yse +gen yem = yempj + yemtj +gen yse = yseag + ysebs +gen temp_em=(yem>yse |(yem==yse & yem!=0)) //assign income to be employed income or self-employed income depending on whether yem>=yse for workers +gen temp_se=(yse>yem) //assign income to be employed income or self-employed income depending on whether yem>yse for workers + +assert temp_em==(1-temp_se) if yem!=0|yse!=0 //checking that non-zero hours working regimes either belong to temp_em or temp_se category +gen temp_nonworker=(yem==0 & yse==0) +assert (temp_em+temp_se+temp_nonworker==1) //checking that all regimes belong to one of the following: temp_em, temp_se, temp_nonworker +//for workers' all states, assume all income are employed income or self-employed income depending which is their major income source in their actual state + +forvalues m=0/$n_workchoices { + forvalues f=0/$n_workchoices { +gen yem_`m'`f' = . +gen yse_`m'`f' = . + +replace yem_`m'`f'=yivwg*lhw_`m'`f'*4.3 if temp_em==1 +replace yse_`m'`f'=0 if temp_em==1 + +replace yse_`m'`f'=yivwg*lhw_`m'`f'*4.3 if temp_se==1 +replace yem_`m'`f'=0 if temp_se==1 + +// for non-workers' counterfacual states, assume all income are employed income +replace yem_`m'`f'=yivwg*lhw_`m'`f'*4.3 if temp_nonworker==1 +replace yse_`m'`f'=0 if temp_nonworker==1 + } +} +gen temp_yem=yem +gen temp_yse=yse +drop yem yse +*NOTE: for both the actual and counter-factural states, yem and yse are computed using wage*discretised hours of work. This now holds automatically because wage is generated as income/discritized hours + + +*----------------------------------------------------------------------------------- +* Generation of new identifiers for each LS alternative +*----------------------------------------------------------------------------------- +/* +foreach var in idhh idperson idpartner idfather idmother { + capture drop `var'* +} +*/ +forvalues m=0/$n_workchoices { + forvalues f=0/$n_workchoices { + foreach var in idhh idperson idpartner idfather idmother { + gen double `var'_`m'`f' = `var' * 100 + `m'*10 + `f' //fake id to cheat EUROMOD + replace `var'_`m'`f' = 0 if `var' == 0 + } + } +} + +*check idperson identifies persons uniquely +duplicates r idperson +gen double temp_idorigperson2=idperson //save original id. idorigperson (within hh id) already existed and not the same as idperson +gen temp_idorigpartner=idpartner +gen temp_idorighh=idhh +gen temp_idorigmother=idmother +gen temp_idorigfather=idfather +drop idperson idpartner idhh idmother idfather + +format temp_id* %15.0g +duplicates r temp_idorigperson2 +/* +foreach var of varlist idhh idperson idpartner idfather idmother lhw yem yse { + quietly rename `var' obs_`var' +} + +*/ +preserve +drop idhh_* idperson_* idpartner_* idfather_* idmother_* lhw_* yem_* yse_* temp_choicehh_* +save full_info-dropped_sample,replace +restore +save beforeReshape-dropped_sample.dta,replace + + +*======================================================================= +* Reshaping data +*======================================================================= + +use beforeReshape-dropped_sample.dta, clear + +keep temp_idorigperson2 idhh_* idperson_* idpartner_* idfather_* idmother_* lhw_* yem_* yse_* temp_choicehh_* + +local reshapevbles = "idhh_ idperson_ idpartner_ idfather_ idmother_ lhw_ yem_ yse_ temp_choicehh_" +reshape long `reshapevbles', i(temp_idorigperson2) j(temp_option) string + +duplicates report temp_idorigperson2 //count how many unique individuals there are +di r(unique_value) + +format id* %20.0g + foreach var in idhh idperson idpartner idfather idmother lhw yem yse temp_choicehh { + rename `var'_ `var' +} +duplicates report idperson // no duplicates +duplicates report idhh + +merge m:1 temp_idorigperson2 using full_info-dropped_sample +assert _merge==3 +drop _merge +gen ind_option = substr(temp_option,1,1) if dgn==1 //alternative bracket for individual male +replace ind_option = substr(temp_option,2,1) if dgn==0 //alternative bracket for individual female +destring ind_option, replace + +gen temp_choice=(ind_option==temp_bracket_0) if dgn==0 //dummy for female individual choice +replace temp_choice=(ind_option==temp_bracket_1) if dgn==1 //dummy for male individual choice +drop ind_option + +destring temp_option, gen (temp_seq) +//check data structure +gsort temp_idorigperson2 temp_seq //Place observations in ascending order of temp_seq within ascending order of original person id +bysort temp_idorigperson2:egen temp_seq2=seq() //give each working regime a label from 1 to $n_choice^2 +assert lhw==0 if temp_not_flexible==1 //not flexible persons should have zero hours of work + +bysort temp_idorigperson2: egen double mean_choicehh=mean(temp_choicehh) //compute the mean of flag of hh choice for the same individual +assert mean_choicehh==1/($n_choices)^2 if temp_couples==1 //for an individual in a flexible couple, 1 option is chosen from ($n_choices)^2 options +assert mean_choicehh==1/($n_choices) if temp_singles==1 //for an individual in "singles", 1 option is chosen from $n_choices options +assert lhw!=. & yem!=. & yse!=. if temp_singles==1|temp_couples==1 //make sure lhw, yse, yse are not missing for sample to be included in labour supply estimation +drop mean_choicehh + +assert temp_choicehh!=. if temp_couples==1 +assert temp_choicehh==. if temp_not_flexible==1 +//note: for each individual in "singles", $n_choices out of $n_choices^2 temp_choicehh are non-missing + +gen count=1 +bysort temp_idorigperson2: egen sum_option=total(count) //compute the sum of options +assert sum_option==$n_choices^2 //up to this point, every individual has $n_choices^2 alternatives +drop count sum_option + + +//update in v8 +drop if temp_choicehh==. & temp_singles==1 //drop invalid rows for singles +duplicates report temp_idorigperson2 //count how many unique individuals there are +di r(unique_value) + +bysort idhh: egen temp_with_singles2=total(temp_singles) //the previously generated temp_with_singles may not be useful because up to this point some singles are dropped already +drop if temp_with_singles2==0 & temp_with_couples==0 & temp_not_flexible==1 //delete not flexible people with no singles or couples to attach to +duplicates report temp_idorigperson2 //count how many unique individuals there are +di r(unique_value) + +gen count=1 +bysort temp_idorigperson2: egen sum_option=total(count) //compute the sum of options + +assert sum_option==$n_choices^2 if temp_alt_nsq==1 //yes +assert sum_option==$n_choices if temp_alt_n==1 +su temp_alt_nsq temp_with_singles temp_with_couples if temp_not_flexible==1 +drop count sum_option +//check again +assert temp_choicehh!=. if temp_couples==1 +assert temp_choicehh!=. if temp_singles==1 //this is new because now singles only have $n_choices kept, solved-contradiction: all aged 16,17,temp_alt_nsq==1, having 12 choices +assert temp_choicehh==. if temp_not_flexible==1 + +*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +* Correct values for benefits 1/2 +*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// @@@ BENEFITS COUNTERFACTUAL ALLOCATION: ASSUMPTION #2(A) @@@ +/*SIMULATED BENEFITS: +Do not worry about them as EUROMOD calculates +the right amount in all choices, given other variables are set correctly. + +*the code below is not relevant for PL +*Notes about bunct_s (unemployment benefit (JSA)): PARTLY SIMULATED, i.e. IT IS SIMULATED BUT THE SIMULATION TAKES SOME VALUES FROM THE DATA. YOU CAN CONSIDER THAT AS "SIMULATED" +//check which variables are used to simulate and manipulate those variables rather than the bunct_s per se, to make bunct_s=0: +preserve +keep id* les bunct +rename les temp_les +rename bunct temp_bunct +save les_bunct,replace //store the original les and bunct for future use if needed +restore +replace les=5 if temp_singles==1|temp_couples==1 +replace bunct=0 if temp_singles==1|temp_couples==1 +*/ + +// @@@ BENEFITS COUNTERFACTUAL ALLOCATION: ASSUMPTION #2(B1) @@@ +/*BENEFITS NOT SIMULATED, COMPATIBLE WITH A WORKING CONDITION BUT DEPEND ON YEM\LHW: +Set them to zero (Otherwise they are positive only in the observed choice and not modelled in the other choices, +and this creates a bias in the estimates of the utility function).*/ +/*Italy +drop if (bmals>0|bmase>0)& lhw==0 & (temp_singles==1|temp_couples==1) // bmals:Maternity payments (lump sum); bmase:Maternity payments (only self emp). +duplicates report temp_idorigperson2 //count how many unique individuals there are +di r(unique_value) + +replace bsa00=0 if temp_singles==1|temp_couples==1 //Social assistance(Minimum Insertion Income ) +replace bsa01=0 if temp_singles==1|temp_couples==1 //Social assistance (Basic Needs Debit Card ) +*/ +/*UK +replace bot=0 if temp_singles==1|temp_couples==1 //other benefits +drop if (bmaer>0|bmana>0)& lhw==0 & (temp_singles==1|temp_couples==1) // bmaer: Statutory maternity pay; bmana: Maternity Allowance (Only 40 obs are dropped from the original whole sample) +*Notes about maternity leave: +// Assume that one who receives at least one of the these benefits (Statutory maternity pay (bmaer) or Maternity Allowance (bmana)) +//as being on maternity leave but think of them as “working”. +*/ + +/*DP: No such benefits in HU (materinity ones are simulated)*/ + +/*PL: +fre bcc //Supplement to the family allowance for parents who take unpaid childcare leave to care for a young child. +fre bchunlp //benefit for unemployed lone parents +fre bma //Maternity allowance +fre ysv //severance payment +*/ +foreach var in bcc bchunlp bma ysv { +replace `var'=0 if temp_singles==1|temp_couples==1 +} +/*(488 real changes made) +(0 real changes made) +(4,236 real changes made) +(20 real changes made) +*/ + +// @@@ BENEFITS COUNTERFACTUAL ALLOCATION: ASSUMPTION #2(B2) @@@ +/*BENEFITS NOT SIMULATED, NOT COMPATIBLE WITH A WORKING CONDITION AND DO NOT DEPEND ON YEM\LHW: +Set them equal to the amount in the observed choice.*/ +/* HU: +bed: education related income (oktatással kapcsolatos támogatás) +bho: housing benefit +botre: other regular benefits - N/A in the dataset +bfaot: other family benefits (includes maternity allowance, child care fee and nursing fee) - N/A in the dataset +*/ + +/*PL: +fre bsaot //neither permanent nor temporary social assistance ==> granted once or occasionally for specific urgent needs +fre bed //scholarships +*/ +cap drop mean_* +foreach var in bed bsaot { +bysort temp_idorigperson2: egen mean_`var'=mean(`var') +//assert `var'==mean_`var' //make sure `var' is equal to the amount in the observed choice +assert abs(`var' - mean_`var') <= 0.1 +drop mean_`var' +} + +// @@@ BENEFITS COUNTERFACTUAL ALLOCATION: ASSUMPTION #2(B3) @@@ +/* +BENEFITS NOT SIMULATED, NOT COMPATIBLE WITH A WORKING CONDITION AND AN INDIVIDUAL RECEIVES THEM IN THE OBSERVED CHOICE (E.G. A DISABILITY BENEFIT): +Exclude this individual from the sample used for labour supply estimates because it means that, in the observed choice, the individual +has some charateristics incompatible with a working condition +*/ +/* Italy +drop if bunct01>0 & (temp_singles==1|temp_couples==1) //Unemployment benefit (Cassa Integrazione Guadagni) +drop if bunct02>0 & (temp_singles==1|temp_couples==1) //Unemployment benefit (Indennita' di Disoccupazione - Mobilita') +drop if bunst>0 & (temp_singles==1|temp_couples==1) //Unemployment benefit s.t. training +drop if yunsv>0 & (temp_singles==1|temp_couples==1) //Severance pay (Liquidazioni da lavoro - TFR) +duplicates report temp_idorigperson2 //count how many unique individuals there are +di r(unique_value) +*/ +/*UK +drop if bedes>0 & (temp_singles==1|temp_couples==1) //Student payments +drop if bedsl>0 & (temp_singles==1|temp_couples==1) //Student Loan +drop if bdioa>0 & (temp_singles==1|temp_couples==1) //Attendance allowance +drop if bdisc>0 & (temp_singles==1|temp_couples==1) //Disability living allowance +drop if bdimb>0 & (temp_singles==1|temp_couples==1) //Disability living (mobility) allowance +drop if bdiscwa>0 & (temp_singles==1|temp_couples==1) //PIP living allowance +drop if bdimbwa>0 & (temp_singles==1|temp_couples==1) // PIP mobility + +drop if bdict0117>0 & (temp_singles==1|temp_couples==1) //Incapacity Benefit 2017 +drop if bdict0118>0 & (temp_singles==1|temp_couples==1) //Incapacity Benefit 2018 +drop if bdict0217>0 & (temp_singles==1|temp_couples==1) //Contributory ESA 2017 +drop if bdict0218>0 & (temp_singles==1|temp_couples==1) //Contributory ESA 2018 + +drop if bdiwi>0 & (temp_singles==1|temp_couples==1) //Industrial injuries pension +drop if bcrdi>0 & (temp_singles==1|temp_couples==1) //Invalid care allowance +drop if bdisv>0 & (temp_singles==1|temp_couples==1) //Severe disablement allowance +drop if bhlwk>0 & (temp_singles==1|temp_couples==1) //Statutory sick pay +drop if buntr>0 & (temp_singles==1|temp_couples==1) //Training allowance +*/ + +/*HU: only pdi - disability pension - could be classified as such +drop if pdi>0 & (temp_singles==1|temp_couples==1) */ + +/*PL: all pensions are compatible with working condition but their earnings are (strictly) limited and may affect their pension. Not sure how to account for that because they are not simulated. +==> opted for removing people on disability pensions completely +fre pdi00 //Disability pension (agricultural and non-agricultural) +fre pdinw //Social pension +fre poa00 //Retirement pension (agricultural and non-agricultural) +fre poafr //Farmer's structural pension +fre poaot //pension : old age : other +fre psu00 //Survivors pension (agricultural and non-agricultural) +fre pyr //Pre-retirement allowance and benefit +*/ +drop if pdi00>0 | pdinw>0 & (temp_singles==1|temp_couples==1) //(5,896 observations deleted) + +////////////////////////////////////////////////////////////// +//Now after benefit correction, check data structure again // +////////////////////////////////////////////////////////////// +gen d=1 +bysort temp_idorigperson2: egen count=total(d) +su count +drop if count!=($n_choices)^2 &temp_alt_nsq==1 +drop if count!=($n_choices) &temp_alt_n==1 + +duplicates report temp_idorigperson2 //count how many unique individuals there are +di r(unique_value) // + +drop d count +gsort temp_idorigperson2 temp_seq //Place observations in ascending order of temp_seq within ascending order of original person id +assert lhw==0 if temp_not_flexible==1 //not flexible persons should have zero hours of work + +bysort temp_idorigperson2: egen double mean_choicehh=mean(temp_choicehh) //compute the mean of flag of hh choice for the same individual +assert mean_choicehh==1/($n_choices)^2 if temp_couples==1 //for an individual in a flexible couple, 1 option is chosen from ($n_choices)^2 options +assert mean_choicehh==1/($n_choices) if temp_singles==1 //for an individual in "singles", 1 option is chosen from $n_choices options +assert lhw!=. & yem!=. & yse!=. if temp_singles==1|temp_couples==1 //make sure lhw, yse, yse are not missing for sample to be included in labour supply estimation + +drop mean_choicehh + +/* +//@@@ tax compliance assumption #1@@@ +//assume full tax compliance, set yseev and ysenr to 0 and hence set TCA off in EUROMOD +//NOTE: an additional step to finish this assumption is to set TCA off which means adding -extSwitch "TCA=off" in the command to run EUROMOD later +// Without this additional step, EUROMOD will still keep the defualt setting, i.e. TCA is on. +//replace yseev=0 +//replace ysenr=0 + +//@@@ tax compliance assumption #2@@@ +//assume no full tax compliance, fill in yseev, ysenr +//replace yseev=0.5*yse //50% SE income reported to tax authority under no full tax compliance +//replace ysenr=0.5*yse //50% SE income not reported to tax authority under no full tax compliance +gen ratio_yseev=yseev/(yseev+ysenr) //this is how the ratio of total se income reported to tax authority (assume this to be the same in every alternative for the same individual) +gen ratio_ysenr=ysenr/(yseev+ysenr) //this is how the ratio of total se income not reported to tax authority (assume this to be the same in every alternative for the same individual) +replace yseev=ratio_yseev*yse if yseev!=0|ysenr!=0 +replace ysenr=ratio_ysenr*yse if yseev!=0|ysenr!=0 +assert yseev!=. +assert ysenr!=. +*/ + +*------------------------------------------------------------ +* Store information not for EUROMOD for later use +*------------------------------------------------------------ + +preserve +keep id* temp* +save temp_file-dropped_sample.dta, replace +restore + +/*VERY IMPORTANT: PL model does not use yem and yse as other models do. PL splits these income by type because different tax regimes are applied to different types of earnings +This needs to be chnaged before data enters the model otherwise there will be no diferences in earnings by alternatives */ +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +foreach var in yempj yemtj yseag ysebs { +gen temp_`var'= `var' +} //save original values + +cap drop yempj yemtj +gen yempj = 0 +replace yempj = yem if temp_yempj>0 & temp_yemtj==0 +gen yemtj = 0 +replace yemtj = yem if temp_yempj==0 & temp_yemtj>0 + +cap drop yseag ysebs +gen yseag = 0 +replace yseag = yse if temp_yseag>0 & temp_ysebs==0 +gen ysebs = 0 +replace ysebs = yse if temp_yseag==0 & temp_ysebs>0 +*end of correction +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +save individuals-dropped_sample.dta,replace + +*======================================================================= +* create EUROMOD input data +*======================================================================= +*---------------------------------------------------------------------------------------------------- +* singles_wage1.dta as input data(Predicted wage for everyone), but not in the EM input folder yet +*----------------------------------------------------------------------------------------------------- +use individuals-dropped_sample,clear +drop temp* //This is because as per EUROMOD conventions, some variables should not appear in the input database. +sort idhh idperson +//drop number* ratio* partner_dgn +drop partner_dgn //ratio* +drop _est_heckman_* +save individuals_wage1-dropped_sample.dta, replace + +*------------------------------------------------------------------------------------------------------------- +* singles_wage2.dta as input data(Predicted wage for non-workers only), but not in the EM input folder yet +*------------------------------------------------------------------------------------------------------------- +use individuals-dropped_sample,clear + +*************************************************** +*// @@@ WAGE IMPUTATION METHOD #wage2@@@ +* make predicted wage=yivwg only for non-workers +*(before this yivwg=predicted wage for everyone) +**************************************************** +replace yivwg=temp_obs_wage if temp_em==1|temp_se==1 //for workers used for the Heckman estimation, wages=actual wages +/* +//for workers' all states, assume all income are employed income or self-employed income depending which is their major income source in their actual state + +replace yem=yivwg*lhw*4.3 if temp_em==1 +replace yse=0 if temp_em==1 + +replace yse=yivwg*lhw*4.3 if temp_se==1 +replace yem=0 if temp_se==1 + +// for non-workers' counterfacual states, assume all income are employed income +replace yem=yivwg*lhw*4.3 if temp_nonworker==1 &temp_choice==0 +*/ + +/*VERY IMPORTANT: here's an additional correction of earnings specific for PL model */ +///////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//for workers' all states, assume all income are employed income or self-employed income depending which is their major income source in their actual state +replace yempj=yivwg*lhw*4.3 if temp_em==1 & yempj>0 +replace yemtj=yivwg*lhw*4.3 if temp_em==1 & yemtj>0 +replace yseag=0 if temp_em==1 +replace ysebs=0 if temp_em==1 + +replace yseag=yivwg*lhw*4.3 if temp_se==1 & yseag>0 +replace ysebs=yivwg*lhw*4.3 if temp_se==1 & ysebs>0 +replace yempj=0 if temp_se==1 +replace yemtj=0 if temp_se==1 + +// for non-workers' counterfacual states, assume all income are employed income +replace yempj=yivwg*lhw*4.3 if temp_nonworker==1 &temp_choice==0 +replace yemtj=yivwg*lhw*4.3 if temp_nonworker==1 &temp_choice==0 +*end of correction +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +drop temp* //This is because as per EUROMOD conventions, some variables should not appear in the input database. +sort idhh idperson + +save individuals_wage2-dropped_sample.dta, replace + +*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +* Correct values for benefits 2/2 +*To be precise, no actual correction is done here, the point is to replicate benefits to +*all alternatives to make a data set called special_partners.dta, +*and append this to the "singles" to make EUROMOD input data +// @@@ BENEFITS COUNTERFACTUAL ALLOCATION: ASSUMPTION #1 @@@ +*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +*loop through wage1, wage2:export as em input file, then run EM, then save output in the result folder for labour supply estimation, +*named "IT_individuals_output_wage`i'" + +foreach i in 1 2{ +//local i=1 +use individuals_wage`i'-dropped_sample,clear +export delimited "$em_input\$file_input.txt", replace nolabel delim(tab) //create input data for EUROMOD +sort idhh +format id* %20.0g +drop ch* +************************************************************ +* Run EUROMOD with Stata +************************************************************ +version 13 +* Call EUROMOD + +capture erase "${em_output}\$file_output.txt" //erase previous output file, this is done in case EUROMOD call from Stata fails, to be sure we are not opening an early run of the model + +shell "${em_exe}" -emPath "${em_models}" -sys PL_2018 -data PL_2019_b3 -forceOutputInEuro //call EUROMOD 1:Program to call 2: path for folder 3: system name 4: dataset to use + +*import EUROMOD RUN + +import delimited "${em_output}\$file_output.txt", clear //import data from txt file in output folder +save individuals_output_wage`i'-dropped_sample,replace + +} + + +log close diff --git a/input_processing/labour_supply/do-files/adult children data preparation/2-singles sample-dropped sample.do b/input_processing/labour_supply/do-files/adult children data preparation/2-singles sample-dropped sample.do new file mode 100644 index 0000000..0590e7d --- /dev/null +++ b/input_processing/labour_supply/do-files/adult children data preparation/2-singles sample-dropped sample.do @@ -0,0 +1,246 @@ +*************************************************************************************************** +* Poland EM data (PL_2019_b3.txt data) +* Labour supply estimation-get sample for adult children and generate the vbls needed for ls +************************************************************************************************** + +global file_log="singles_sample-dropped sample" + +global n_choices = 4 // 4 choices: no work, plus 3 hours brackets. +global n_workchoices = $n_choices - 1 // 3 choices with positive supply of hours, 1 choice with 0 hours. + +cd "$local_data" + +capture log close +log using "$file_log", replace +pwd +clear all +set seed 1 //same seed gives same results + +*version 15 + +//update 1/2/2021: at the end of the do file, divide this sample into two subsamples: singles_indep_wage`i'-dropped_sample and singles_dep_wage`i'-dropped_sample + +*loop through wage1, wage2: hours of work estimation for each gender (triple loop) + +//loop over wage1, wage2 +foreach i in 1 2{ //loop begin for wage imputation method +use "individuals_output_wage`i'-dropped_sample",clear +//assert bunct_s==0 //N/A for IT: making sure unemployment benefit (JSA): bunct_s=0 for every alternatives for everyone +gen sim_flag=0 //needed because this should contain the same variables as in dataset to be appended + +merge m:1 idperson using "temp_file-dropped_sample.dta" //add additional information +assert _merge==3 +drop _merge + +duplicates report temp_idorigperson2 //count how many unique individuals there are +di r(unique_value) + +gen d40=(dag>=40) + +gen d45=(dag>=45) + +//dummy of living with elderly (aged>=50), including themselves +gen d50=(dag>=50) +bysort temp_idorighh:egen d_with_elderly50=total(d50) //up to here d_with_elderly60=the no. of elderly in hh* $n_choices +replace d_with_elderly50=(d_with_elderly50>0) +label variable d_with_elderly50 "1(living with people aged 50+)" + +//dummy of living with elderly (aged>=55), including themselves +gen d55=(dag>=55) +bysort temp_idorighh:egen d_with_elderly55=total(d55) //up to here d_with_elderly60=the no. of elderly in hh* $n_choices +replace d_with_elderly55=(d_with_elderly55>0) +label variable d_with_elderly55 "1(living with people aged 55+)" + +//dummy of living with elderly (aged>=60), including themselves +gen d60=(dag>=60) +bysort temp_idorighh:egen d_with_elderly60=total(d60) //up to here d_with_elderly60=the no. of elderly in hh* $n_choices +replace d_with_elderly60=(d_with_elderly60>0) +label variable d_with_elderly60 "1(living with people aged 60+)" + +//dummy of living with elderly (aged>=65), including themselves +gen d65=(dag>=65) +bysort temp_idorighh:egen d_with_elderly65=total(d65) //up to here d_with_elderly60=the no. of elderly in hh* $n_choices +replace d_with_elderly65=(d_with_elderly65>0) +label variable d_with_elderly65 "1(living with people aged 65+)" + +//dummy of living with elderly (aged>=70), including themselves +gen d70=(dag>=70) +bysort temp_idorighh:egen d_with_elderly70=total(d70) //up to here d_with_elderly60=the no. of elderly in hh* $n_choices +replace d_with_elderly70=(d_with_elderly70>0) +label variable d_with_elderly70 "1(living with people aged 70+)" + +//dummy of living with elderly (aged>=75), including themselves +gen d75=(dag>=75) +bysort temp_idorighh:egen d_with_elderly75=total(d75) //up to here d_with_elderly60=the no. of elderly in hh* $n_choices +replace d_with_elderly75=(d_with_elderly75>0) +label variable d_with_elderly75 "1(living with people aged 75+)" + +label variable les "economic status" //les=4: pensioner +gen d_se=(les==2) //dummy of being self-employed +label variable d_se "1(self-employed)" + +******** + + +bysort idhh: egen hhcon=sum(ils_dispy) //hh income, should be done before keeping only the target sample +//assert hhcon==. if sim_flag==1 +label variable hhcon "income" +keep if temp_singles==1 &temp_choicehh!=. //target sample: "singles", and keep only $n_choices rows for each individual +duplicates report temp_idorigperson2 //count how many unique individuals there are +di r(unique_value) + +//check data structure +bysort temp_idorigperson2: egen double mean_choicehh=mean(temp_choicehh) //compute the mean of flag of hh choice for the same individual +assert mean_choicehh==1/($n_choices) if temp_singles==1 //for an individual in "singles", 1 option is chosen from $n_choices options +assert lhw!=. & yem!=. & yse!=. if temp_singles==1 //make sure lhw, yse, yse are not missing for sample to be included in labour supply estimation + +//generation of vbls +//house ownership +gen d_owner=(amrtn==1|amrtn==2) +label variable d_owner "house owner (on mortgage or outright)" + +gen d_owner_out=(amrtn==2) //own outright +label variable d_owner_out "house owner (outright)" + +gen d_owner_mort=(amrtn==1) //own on mortgage +label variable d_owner_out "house owner (on mortgage)" + +gen d_renter_social=(amrtn==5) //own on mortgage +label variable d_renter_social "house renter (social rented)" + +*********************** +gen leisure=24*7-lhw //define leisure for utility function +label variable leisure "leisure" + +//participation dummy +gen fixed_cost=(lhw>0) //define a fixed-cost of work (dummy) +label variable fixed_cost "fixed cost for labour" + +//gen part-time fixed cost +gen part_fixed_cost=(lhw<40 &lhw>0) //in HU full-time work is 40 hours per week +label variable part_fixed_cost "fixed cost for part-time work" + +//gen full-time fixed cost +gen full_fixed_cost=(lhw>=40) +label variable full_fixed_cost "fixed cost for full-time work" + +//gen interaction of fixed cost with gender +gen fixc_dgn=fixed_cost*dgn +lab var fixc_dgn "fixed cost for labour$\times$1(male)" + +//social norm? +gen hrs_40=(lhw==40) +label var hrs_40 "1(weekly working hours=40)" + +gen hrs_40plus=(lhw>=40) +label var hrs_40plus "1(weekly working hours>=40)" + +//gen interaction of 40 hours dummy with gender +gen hrs_40_dgn=hrs_40*dgn +lab var hrs_40_dgn "1(weekly working hours=40)\times$1(male)" + +gen hrs_40plus_dgn=hrs_40plus*dgn +lab var hrs_40plus_dgn "1(weekly working hours=40plus)\times$1(male)" + +//experience variable +//gen liwwh_0 = (liwwh==0) //zero experience +gen liwwh_1 = (liwwh>=0 & liwwh<1) //less than a year experience +gen liwwh_2 = (liwwh>=1 & liwwh<5) //1 to 5 years experience +gen liwwh_3 = (liwwh>=5) //5+ years experience +//lab var liwwh_0 "no experience" +lab var liwwh_1 "0-1 years (new entrants)" +lab var liwwh_2 "1-5 years (some experience)" +lab var liwwh_3 "5+ years (highly experienced)" + +gen ln_liwwh = ln(liwwh + 1) + +foreach var in liwwh { + gen `var'2=(`var'^2) + label variable `var'2 "`var'^2" + } + +* Generation of variables squared + foreach var in leisure hhcon { + gen `var'2=(`var'^2) + label variable `var'2 "`var'^2" + } + +//rescale age and age^2 +gen age_100=dag/100 +label variable age_100 "age/100" + +gen age2_10000= temp_age2/10000 +label variable age2_10000 "age^2/10000" + +//rescale hhcon and hhcon^2 +gen hhcon_100=hhcon/100 +label variable hhcon_100 "income/100" + +gen hhcon2_10000= hhcon2/10000 +label variable hhcon2_10000 "income^2/10000" + +*generation of interactions with household income +global incomex "age_100 age2_10000 temp_n_ch temp_d_ch2 d_owner_out d_owner_mort d_renter_social temp_hhsize temp_dhe_1 temp_dhe_2 temp_dhe_3 temp_dhe_4 temp_dhe_5" +foreach x of varlist $incomex{ +gen hhcon_100_`x'=hhcon_100*`x' +local varlabel : var label `x' +label variable hhcon_100_`x' "income/100#`varlabel'" +} + +/*combining regions +//North West + North East= North +gen temp_north=temp_region1+temp_region2 +lab var temp_north "North" +//South + Islands= South +gen temp_south_islands=temp_region4+temp_region5 +lab var temp_south_islands "South and Islands" +*/ + +*generation of interactions with fixed cost for labour +global fixedcostx "temp_n_ch temp_d_ch2 temp_p_sick_dis temp_p_student d_owner_out d_owner_mort d_renter_social temp_p_pensioner temp_d_deh_L temp_d_deh_M temp_d_deh_H d60 d65 d70 temp_region1 temp_region2 temp_region3 temp_region4 temp_region5 temp_region6 temp_region7 temp_dhe_1 temp_dhe_2 temp_dhe_3 temp_dhe_4 temp_dhe_5" +foreach x of varlist $fixedcostx{ +gen fixc_`x'=fixed_cost*`x' +local varlabel : var label `x' +label variable fixc_`x' "fixed cost for labour#`varlabel'" +} + +*generation of interactions with leisure +global lx "hhcon_100 age_100 age2_10000 temp_n_ch temp_d_ch* temp_d_deh_L temp_d_deh_M temp_d_deh_H temp_region1 temp_region2 temp_region3 temp_region4 temp_region5 temp_region6 temp_region7 d_owner_out d_owner_mort d_renter_social temp_hhsize temp_dhe_1 temp_dhe_2 temp_dhe_3 temp_dhe_4 temp_dhe_5" +foreach x of varlist $lx{ +gen lei_`x'=leisure*`x' +local varlabel : var label `x' +label variable lei_`x' "leisure#`varlabel'" +} + +*estimate labour supply model and compute predicted choices +// LS model of choices (0,20,40,50). By default assumes quadratic utility. verbose shows more detail + +bysort temp_idorigperson2: egen min_hhcon=min(hhcon) +drop if min_hhcon<=0 //consumption is not allowed to be 0 or negative for lslogit +duplicates report temp_idorigperson2 //count how many unique individuals there are +di r(unique_value) + +//divide this sample into two subsamples: + +/*DP: Added filter for adult children for consistency with simulations , 15 Nob 2025 */ +//singles_indep_wage`i'-dropped_sample +preserve +keep if temp_singles_indep==1 & temp_adultchildflag==1 +duplicates report temp_idorigperson2 //count how many unique individuals there are +di r(unique_value) + +save singles_indep_wage`i'-dropped_sample,replace +restore + +//singles_dep_wage`i'-dropped_sample +preserve +keep if temp_singles_dep==1 +save singles_dep_wage`i'-dropped_sample,replace +restore + +save singles_wage`i'-dropped_sample,replace //still save this as will be used in EM sample (1.1wage) + +} //loop end for wage imputation method +log close + + diff --git a/input_processing/labour_supply/do-files/adult children data preparation/3-EM single wage elasticity-adult_ch.do b/input_processing/labour_supply/do-files/adult children data preparation/3-EM single wage elasticity-adult_ch.do new file mode 100644 index 0000000..0b780fd --- /dev/null +++ b/input_processing/labour_supply/do-files/adult children data preparation/3-EM single wage elasticity-adult_ch.do @@ -0,0 +1,96 @@ +************************************************************************** +* Poland EM data (PL_2019_b3.txt data) +*run EM to get the ils_dispy for sample of adult children resulting from a 10% increase in gross wage +************************************************************************ + +global n_choices = 4 // 4 choices: no work, plus 4 hours brackets. +global n_workchoices = $n_choices - 1 // 3 choices with positive supply of hours, 1 choice with 0 hours. + +//update 1/2/2021: when Extract the sample of "singles" and define variables, save separately as sim_singles_indep_110_IT_individuals_output_wage`i'-dropped_sample +//& sim_singles_dep_110_IT_individuals_output_wage`i'-dropped_sample + +cd "$local_data" + +capture log close +log using "$file_log", replace +pwd + +foreach i in 1 2{ //loop begin for wage imputation method +//local i=1 //only do for wage1 +use individuals_wage`i'-dropped_sample,clear +merge 1:1 idperson using temp_file-dropped_sample.dta //add additional information +drop _merge +keep if temp_alt_n==1 //reduce EUROMOD burden + +replace yivwg=1.1*yivwg //to be safe (new) +*replace yem=1.1*yem //increase gross wage by 10% +*replace yse=1.1*yse //increase gross wage by 10% +replace yempj=1.1*yempj +replace yemtj=1.1*yemtj +replace yseag=1.1*yseag +replace ysebs=1.1*ysebs + +/* +//for self-employed income, change yse, yseev, ysenr to be on the safe side, and then EM decides which vbls use (either yseev+ysenr or yse) depending on the switch of the TCA +replace yseev=1.1*yseev //increase gross wage by 10% +replace ysenr=1.1*ysenr //increase gross wage by 10% +*/ + +drop temp* +sort idhh +export delimited "$em_input\$file_input.txt", replace nolabel delim(tab) //create input data for EUROMOD +************************************************************ +* Run EUROMOD with Stata +************************************************************ +version 13 +* Call EUROMOD + +capture erase "${em_output}\$file_output.txt" //erase previous output file, this is done in case EUROMOD call from Stata fails, to be sure we are not opening an early run of the model + +shell "${em_exe}" -emPath "${em_models}" -sys PL_2018 -data PL_2019_b3 -forceOutputInEuro //call EUROMOD 1:Program to call 2: path for folder 3: system name 4: dataset to use + +*import EUROMOD RUN +import delimited "${em_output}\$file_output.txt", clear //import data from txt file in output folder +gen sim_flag=1 //to indicate that these are simulated observations +rename ils_dispy sim_ils_dispy +rename yem sim_yem +rename yse sim_yse +bysort idhh: egen sim_hhcon=sum(sim_ils_dispy) //hh income, should be done before keeping only the target sample +keep idperson sim_ils_dispy sim_hhcon sim_yem sim_yse +save sim_110_individuals_output_wage`i'-dropped_sample,replace +} //loop end for wage imputation method + +*======================================================================= +* Extract the sample of "singles" and define variables +*======================================================================= +foreach i in 1 2{ //loop begin for wage imputation method +//local i=1 +use "sim_110_individuals_output_wage`i'-dropped_sample",clear +merge 1:1 idperson using "singles_wage`i'-dropped_sample.dta" +keep if _merge==3 +drop _merge +su hhcon sim_hhcon +replace hhcon=sim_hhcon //make hhcon=simulated hhcon +assert sim_hhcon==hhcon +replace yem=sim_yem +replace yse=sim_yse +replace ils_dispy=sim_ils_dispy //new + +drop sim_* +gen sim_flag=1 +//sim_singles_indep_110_individuals_output_wage`i'-dropped_sample +preserve +keep if temp_singles_indep==1 & temp_adultchildflag==1 +save "sim_singles_indep_110_individuals_output_wage`i'-dropped_sample",replace +restore + +//sim_singles_dep_110_individuals_output_wage`i'-dropped_sample +preserve +keep if temp_singles_dep==1 +save "sim_singles_dep_110_individuals_output_wage`i'-dropped_sample",replace +restore + +//save sim_singles_110_individuals_output_wage`i'-dropped_sample,replace +} //loop end for wage imputation method + +log close diff --git a/input_processing/labour_supply/do-files/model specifications/4a-singles_indep_elast-std model - final.do b/input_processing/labour_supply/do-files/model specifications/4a-singles_indep_elast-std model - final.do new file mode 100644 index 0000000..f2eb055 --- /dev/null +++ b/input_processing/labour_supply/do-files/model specifications/4a-singles_indep_elast-std model - final.do @@ -0,0 +1,480 @@ +************************************************************************** +* EU SILC (PL_2019_b3) +* Labour supply estimation for independent singles +************************************************************************ +/* +// @@@ SPECIFICATION @@@ +Consumption-leisure preferences using a quadratic utility function with fixed costs. +Separate models for men and women, using predicted wages for everyone +*/ + +global file_log="${log}/singles_indep_elast-std-simple" +global n_choices = 4 // 4 choices: no work, plus 3 hours brackets. +global n_draws=100 //modify when computing elasticity 100 + +cd "$local_data" + +*Housekeeping +capture log close +*office PC + +log using "$file_log", replace +pwd +clear all +set seed 1 + +*version 15 + + +*======================================================================= +* estimate hours of work for female and male, respectively +*======================================================================= +//drop monthly hhcon<10 +*capture drop min_hhcon +*bysort temp_idorigperson2: egen min_hhcon=min(hhcon) +*drop if min_hhcon<=10 + + + +*use singles_indep_wage1,clear //use predicted wages for everyone +use singles_indep_wage$impmethod, clear //use observed wage for workers + +foreach gender in 0 1{ //loop begin for gender +capture drop temp_pred_lhw1_`gender' +capture drop pred_prob_`gender' +capture drop pred_utility_`gender' +capture drop pred_utility2_`gender' +capture drop max_utility2_`gender' +capture drop pred_choice2_`gender' +capture drop pred_lhw2_`gender' +capture drop temp_pred_lhw2_`gender' +capture drop epsilon2 + +capture drop pred_choice1_`gender' +capture drop pred_utility1_`gender' +capture drop max_utility1_`gender' +capture drop pred_choice1_`gender' +capture drop pred_lhw1_`gender' +capture drop temp_pred_lhw1_`gender' + + +//female variables +global vars_0 "hhcon_100 hhcon2_10000 leisure leisure2 lei_hhcon_100 hrs_40plus" //fixed_cost +//male variables +global vars_1 "hhcon_100 hhcon2_10000 leisure leisure2 lei_hhcon_100 hrs_40plus" //fixed_cost + +************************************************************************************************************************************** +drop if sim_flag==1 //make sure the data is actual at this point +//clogit temp_choicehh ${vars_`gender'} if dgn==`gender' , group (temp_idorigperson2) //estimate only on actual data (sim_flag==0) +asclogit temp_choicehh ${vars_`gender'} if dgn==`gender', case(temp_idorigperson2) alt(temp_seq) casevar(liwwh liwwh2) nocons +************************************************************************************************************************************** + +gen ll_`gender' = (e(ll)) + + +eststo singles_`gender'_wage$impmethod +gen sample_`gender'=(e(sample)) + +//version 13 + +////////////////////////////////////// +//output estimated results to Excel // +////////////////////////////////////// +* output labels +if (`gender' == 0){ +putexcel set "$results/reg_labourSupplyUtility_PL", sheet("Single_female") modify + +putexcel A1 = "REGRESSOR" +putexcel A2 = "IncomeDiv100" +putexcel A3 = "IncomeSqDiv10000" +putexcel A4 = "FemaleLeisure" +putexcel A5 = "FemaleLeisureSq" +putexcel A6 = "FemaleLeisure_IncomeDiv100" +putexcel A7 = "Hrs_40plus_Female" +putexcel A8 = "Liwwh_1" +putexcel A9 = "LiwwhSq_1" +putexcel A10 = "Liwwh_2" +putexcel A11 = "LiwwhSq_2" +putexcel A12 = "Liwwh_3" +putexcel A13 = "LiwwhSq_3" + +putexcel B1 = "COEFFICIENT" +putexcel C1 = "IncomeDiv100" +putexcel D1 = "IncomeSqDiv10000" +putexcel E1 = "FemaleLeisure" +putexcel F1 = "FemaleLeisureSq" +putexcel G1 = "FemaleLeisure_IncomeDiv100" +putexcel H1 = "Hrs_40plus_Female" +putexcel I1 = "Liwwh_1" +putexcel J1 = "LiwwhSq_1" +putexcel K1 = "Liwwh_2" +putexcel L1 = "LiwwhSq_2" +putexcel M1 = "Liwwh_3" +putexcel N1 = "LiwwhSq_3" +} + +else{ +putexcel set "$results/reg_labourSupplyUtility_PL", sheet("Single_male") modify + +putexcel A1 = "REGRESSOR" +putexcel A2 = "IncomeDiv100" +putexcel A3 = "IncomeSqDiv10000" +putexcel A4 = "MaleLeisure" +putexcel A5 = "MaleLeisureSq" +putexcel A6 = "MaleLeisure_IncomeDiv100" +putexcel A7 = "Hrs_40plus_Male" +putexcel A8 = "Liwwh_10" +putexcel A9 = "LiwwhSq_10" +putexcel A10 = "Liwwh_20" +putexcel A11 = "LiwwhSq_20" +putexcel A12 = "Liwwh_30" +putexcel A13 = "LiwwhSq_30" + +putexcel B1 = "COEFFICIENT" +putexcel C1 = "IncomeDiv100" +putexcel D1 = "IncomeSqDiv10000" +putexcel E1 = "MaleLeisure" +putexcel F1 = "MaleLeisureSq" +putexcel G1 = "MaleLeisure_IncomeDiv100" +putexcel H1 = "Hrs_40plus_Male" +putexcel I1 = "Liwwh_10" +putexcel J1 = "LiwwhSq_10" +putexcel K1 = "Liwwh_20" +putexcel L1 = "LiwwhSq_20" +putexcel M1 = "Liwwh_30" +putexcel N1 = "LiwwhSq_30" + +} + +* output coefficients +matrix results = r(table) +matrix results = results[1..6,1...]' //extract the first six rows of results, and then transpose results +putexcel B2 = matrix(results /*, names*/) //names nformat(number_d2) //write estimates in Excel from cell B2 + + +* output variance-covariance matrix +matrix results=e(V) +putexcel C2 = matrix(results /*, names*/ ) //names nformat(number_d2) //write e(V) in Excel from cell C2 + + +****************** +*Predict choices * +****************** +predict double de_pred_utility_`gender' if dgn==`gender' , xb //deterministic component of utility + +set seed 1 //same seed gives same results +gen double epsilon_`gender'= -log(-log(runiform())) //random draw from an extreme value distribution (required for counterfactual) +gen double pred_utility_`gender'= de_pred_utility_`gender'+epsilon_`gender' if dgn==`gender' //utility=deterministic utility+stochastic utility + +bys temp_idorigperson2: egen double max_utility_`gender'=max(pred_utility_`gender') if dgn==`gender' //for each agent highest utility +//gen pred_choice2_`gender'=(max_utility2_`gender'==pred_utility2_`gender') if dgn==`gender' //dummy for predicted choices +//gen pred_lhw2_`gender'=lhw if pred_choice2_`gender'==1& dgn==`gender' //predicted hours of work +gen pred_lhw_`gender'=lhw if max_utility_`gender'==pred_utility_`gender' & dgn==`gender' //predicted hours of work (only present in the chosen row) +replace pred_lhw_`gender'=0 if pred_lhw_`gender'==. +bys temp_idorigperson2: egen temp_pred_lhw_`gender'=total(pred_lhw_`gender') if dgn==`gender', missing //expand pred_lhw2 to all alternatives (missing as 0) + + +********************* +*Marginal utilities * +********************* + +*this is inside the gender loop +capture drop dU_c_`gender' +capture drop dU_lei_`gender' +capture drop dU2_c_`gender' +capture drop dU2_lei_`gender' + + *----------------------------------------------------------------- + * First differential of utility w.r.t. disposable income + *----------------------------------------------------------------- + gen dU_c_`gender'=_b[hhcon_100]+2*hhcon_100*_b[hhcon2_10000] +leisure*_b[lei_hhcon_100] + su dU_c_`gender' if temp_choicehh==1 &dgn==`gender' //& sim_flag==0 + + + *----------------------------------------------------------------- + * Second differential of utility w.r.t. disposable income + *----------------------------------------------------------------- + gen dU2_c_`gender'=2*_b[hhcon2_10000] + su dU2_c_`gender' if temp_choicehh==1 &dgn==`gender' //& sim_flag==0 + + + *----------------------------------------------------------------- + * First differential of utility w.r.t. leisure + *----------------------------------------------------------------- + gen double dU_lei_`gender'=_b[leisure]+2*leisure*_b[leisure2]+hhcon_100*_b[lei_hhcon_100] + su dU_lei_`gender' if temp_choicehh==1 &dgn==`gender' //& sim_flag==0 + + + *----------------------------------------------------------------- + * Second differential of utility w.r.t. leisure + *----------------------------------------------------------------- + gen dU2_lei_`gender'=2*_b[leisure2] + su dU2_lei_`gender' if temp_choicehh==1 &dgn==`gender' //& sim_flag==0 + + +*************************************************** +* Predict prob for both actual and simulated data * +*************************************************** +capture drop choice_prob_`gender' +capture drop hrs_hat_`gender' +capture drop E_hrs_hat_`gender' +capture drop prob_work_`gender' + +predict choice_prob_`gender' if dgn==`gender' //probability of a positive outcome + + +*the highest utility=deterministic+stochastic is chosen + +append using "sim_singles_indep_110_individuals_output_wage$impmethod" //for "singles" sample, get simulated ils_dispy resulting from 10% increase of gross wage +//predict double pred_prob_`gender' if dgn==`gender'& sim_flag==0 //predicted probabilities (deterministic) +//predict double de_pred_utility_`gender' if dgn==`gender' & sim_flag==0, xb //deterministic component of utility +sum de_pred_utility_`gender' if dgn==`gender' & sim_flag==0 +//v15 update +predict double sim_pred_prob_`gender' if dgn==`gender'& sim_flag==1 //predicted probabilities (deterministic) + +predict double sim_de_pred_utility_`gender' if dgn==`gender' & sim_flag==1, xb //for simulated hhcon, deterministic component of utility +su sim_de_pred_utility_`gender' if dgn==`gender' & sim_flag==1 + + +capture drop hrs_elas_`gender'_* +set seed 339487731 +//v15 update: loop for random draw +//add loop beginning +forvalues i = 1/$n_draws { +capture drop epsilon +capture drop pred_utility_`gender' +capture drop max_utility_`gender' +capture drop pred_lhw_`gender' +capture drop temp_pred_lhw_`gender' + +capture drop sim_pred_utility_`gender' +capture drop sim_max_utility_`gender' +capture drop sim_pred_lhw_`gender' +capture drop sim_temp_pred_lhw_`gender' + + +gen double epsilon= -log(-log(runiform())) //random draw from an extreme value distribution (required for counterfactual) +gen double pred_utility_`gender'= de_pred_utility_`gender'+epsilon if dgn==`gender' & sim_flag==0 //utility=deterministic utility+stochastic utility + +bys temp_idorigperson2: egen double max_utility_`gender'=max(pred_utility_`gender') if dgn==`gender' & sim_flag==0 //for each agent highest utility +//gen pred_choice2_`gender'=(max_utility2_`gender'==pred_utility2_`gender') if dgn==`gender' //dummy for predicted choices +//gen pred_lhw2_`gender'=lhw if pred_choice2_`gender'==1& dgn==`gender' //predicted hours of work +gen pred_lhw_`gender'=lhw if max_utility_`gender'==pred_utility_`gender' & dgn==`gender' & sim_flag==0 //predicted hours of work (only present in the chosen row) +replace pred_lhw_`gender'=0 if pred_lhw_`gender'==. +bys temp_idorigperson2: egen temp_pred_lhw_`gender'=total(pred_lhw_`gender') if dgn==`gender', missing //expand pred_lhw2 to all alternatives (missing as 0) + +*replace pred_lhw_0=temp_pred_lhw_0 if dgn==`gender' & pred_lhw_0==. //expand pred_lhw2 to all alternatives + + +//v15 update: predict optimal hours for sim_hhcon +gen double sim_pred_utility_`gender'= sim_de_pred_utility_`gender'+epsilon if dgn==`gender' & sim_flag==1 //utility=deterministic utility+stochastic utility +bys temp_idorigperson2: egen double sim_max_utility_`gender'=max(sim_pred_utility_`gender') if dgn==`gender' & sim_flag==1 //for each agent highest utility +//gen pred_choice2_`gender'=(max_utility2_`gender'==pred_utility2_`gender') if dgn==`gender' //dummy for predicted choices +//gen pred_lhw2_`gender'=lhw if pred_choice2_`gender'==1& dgn==`gender' //predicted hours of work +gen sim_pred_lhw_`gender'=lhw if sim_max_utility_`gender'==sim_pred_utility_`gender' & dgn==`gender' & sim_flag==1 //predicted hours of work (only present in the chosen row) +bys temp_idorigperson2: egen sim_temp_pred_lhw_`gender'=total(sim_pred_lhw_`gender') if dgn==`gender', missing //expand pred_lhw2 to all alternatives (missing as 0) + +*replace sim_pred_lhw_`gender'=sim_temp_pred_lhw_`gender' if dgn==`gender' & sim_pred_lhw_`gender'==. //expand pred_lhw2 to all alternatives + + +**************** +*Elasticities * +**************** +gen hrs_elas_`gender'_`i'=10*(sim_temp_pred_lhw_`gender'-temp_pred_lhw_`gender')/temp_pred_lhw_`gender' if dgn==`gender' & temp_choicehh==1 + +} //end of draws loop??? + +order hrs_elas_`gender'_*, last +egen mean_hrs_elas_`gender'=rmean(hrs_elas_`gender'_1-hrs_elas_`gender'_$n_draws) if temp_choicehh==1 & sample_`gender'==1 // single female's/male's hours elasticity (for each obs) +su mean_hrs_elas_`gender' if temp_choicehh==1 & sample_`gender'==1,d //summary of single females's hours elasticity across observations + + +*version 14 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//hours fit graph (histograms for two genders)(with the last random draw as previous draws are all overwritten)////// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +if (`gender'==0) { +twoway (histogram lhw if temp_choice==1 & sample_`gender'==1, discrete percent color(green)) /// + (histogram temp_pred_lhw_`gender' if temp_choice==1 & sample_`gender'==1, discrete percent color(none) lcolor(black)), /// + legend(order(1 "observed" 2 "predicted" )) /// + subtitle("Independent singles, Women") xtitle("weekly hours worked") /// + xlabel(0 20 40 50, valuelabel ) +} +else { +twoway (histogram lhw if temp_choice==1 & sample_`gender'==1, discrete percent color(green)) /// + (histogram temp_pred_lhw_`gender' if temp_choice==1 & sample_`gender'==1, discrete percent fcolor(none) lcolor(black)), /// + legend(order(1 "observed" 2 "predicted" )) /// + subtitle("Independent singles, Men") xtitle("weekly hours worked") /// + xlabel(0 20 40 50, valuelabel ) +} +graph save "$results_ls/singles-ind/his_hoursfit_`gender'.gph", replace + +} //end of loop end for gender + + +graph combine "$results_ls/singles-ind/his_hoursfit_0" "$results_ls/singles-ind/his_hoursfit_1" +graph export "$results_ls/singles-ind/his_hoursfit_bothgenders_indep.png", as(png) replace + + +///////////////////////////////////////// +//graph of elasticity for both genders // +///////////////////////////////////////// +twoway (histogram mean_hrs_elas_0 if temp_choicehh==1 & sample_0==1 , color(green) ) /// + (histogram mean_hrs_elas_1 if temp_choicehh==1 & sample_1==1, /// + fcolor(none) lcolor(black)), legend(order(1 "female single" 2 "male single" )) /// + subtitle("Hours elasticity") +graph export "$results_ls/singles-ind/hrs_elas_single_indep.png", as(png) replace + + +sum ils_dispy +//save singles_wage$impmethod.dta, replace //try not to save too many data files to save disc space + + + +/////////////////////////////// +//histogram of du/dc, du/dlei// +/////////////////////////////// +twoway (histogram dU_c_0 if sample_0==1 &temp_choicehh==1 , color(green) ) /// + (histogram dU_c_1 if sample_1==1 &temp_choicehh==1, /// + fcolor(none) lcolor(black)), legend(order(1 "female single" 2 "male single" )) /// + subtitle("MU wrt income") + + graph export "$results_ls/singles-ind/dUdc_single_indep.png", as(png) replace + + +twoway (histogram dU_lei_0 if sample_0==1& temp_choicehh==1, color(green) ) /// + (histogram dU_lei_1 if sample_1==1 &temp_choicehh==1, /// + fcolor(none) lcolor(black)), legend(order(1 "female single" 2 "male single" )) /// + subtitle("MU wrt leisure") + + graph export "$results_ls/singles-ind/dUdlei_single_indep.png", as(png) replace + +su dU_c_0 dU_lei_0 dU2_c_0 dU2_lei_0 if sample_0==1& temp_choicehh==1 //female single +su dU_c_1 dU_lei_1 dU2_c_1 dU2_lei_1 if sample_1==1 & temp_choicehh==1 //male single + + +///////////////////////////////////// +//export estimation results to tex // +///////////////////////////////////// +esttab singles_0_wage$impmethod singles_1_wage$impmethod using "$results_ls/singles-ind/ls_single_indep_10.tex", replace label cells(b(star fmt(3))) stats(ll r2_p N ) nonumbers mtitles("Men" "Women") /// +collabels(none) /// +title(Labour supply (utility function) estimation: Independent singles. /// + Notes: Income in hundreds of HUF. /// +\label{tab:hours-singles}) /// +varlabels(r2_p pseudo-R^2) /// +addnote("*** Results significant at 0.1\%, ** 1\%, * 5\%.") //for writing tex including female and male(including at least three non-zero digits) + +esttab singles_0_wage$impmethod singles_1_wage$impmethod using "$results_ls/singles-ind/ls_single_indep_10.csv", replace label cells(b(star fmt(3))) stats(ll r2_p N ) nonumbers mtitles("Men" "Women") /// +collabels(none) /// +title(Labour supply (utility function) estimation: Independent singles. /// + Notes: Income in hundreds of HUF. /// +\label{tab:hours-singles}) /// +varlabels(r2_p pseudo-R^2) /// +addnote("*** Results significant at 0.1\%, ** 1\%, * 5\%.") //for writing csv including female and male(including at least three non-zero digits) + + + +///////////////////////// +////Income deciles ///// +///////////////////////// +xtile dec_hhcon0 = hhcon if sample_0==1 &temp_choicehh==1, nq(10) //create decile variable for single female +xtile dec_hhcon1 = hhcon if sample_1==1 &temp_choicehh==1, nq(10) //create decile variable for single male +bysort dec_hhcon0:su mean_hrs_elas_0 if sample_0==1 &temp_choicehh==1 + +bysort dec_hhcon1:su mean_hrs_elas_1 if sample_1==1 &temp_choicehh==1 +//box plot +label var dec_hhcon0 "income decile" +graph box mean_hrs_elas_0 if temp_choicehh==1, ytitle(wage elasticity) over(dec_hhcon0) subtitle("Independent singles, Women") note("Income decile" /// +"Lines indicate upper adjacent value, 75th percentile, median, 25th percentile, lower adjacent value.") + + graph export "$results_ls/singles-ind/wage_elas0_indep.png", as(png) replace + +graph box mean_hrs_elas_1 if temp_choicehh==1, ytitle(wage elasticity) over(dec_hhcon1) subtitle("Independent singles, Men") note("Income decile" /// +"Lines indicate upper adjacent value, 75th percentile, median, 25th percentile, lower adjacent value.") + + graph export "$results_ls/singles-ind/wage_elas1_indep.png", as(png) replace + + +/////////////////// +///summary stats // +/////////////////// +*percent of obs with positive marginal utilities +foreach i in dU_c dU_lei{ +foreach gender in 0 1{ +gen `i'_`gender'positive=(`i'_`gender'>0) +su `i'_`gender'positive if sample_`gender'==1 & temp_choicehh==1 +} +} + +*percent of obs with negative marginal utilities +foreach i in dU_c dU_lei{ +foreach gender in 0 1{ +cap drop `i'_`gender'negative +gen `i'_`gender'negative=(`i'_`gender'<0) +sum `i'_`gender'negative if sample_`gender'==1 & temp_choicehh==1 +} +} + +///////////////////////////////////////////// +//output to Excel file with summary stats /// +///////////////////////////////////////////// +putexcel set "${summary_table}", sheet(${sheet}, replace) modify + +putexcel A2=("Wage elasticities of hours of work") +putexcel A3=("Independent singles, women") +putexcel A4=("Independent singles, men") +mean mean_hrs_elas_0 if sample_0==1 &temp_choicehh==1 +putexcel B3=matrix(e(b)') +mean mean_hrs_elas_1 if sample_1==1 &temp_choicehh==1 +putexcel B4=matrix(e(b)') + +putexcel A9=("% obs with negative marginal utility wrt income") +putexcel A10=("Independent singles, women") +putexcel A11=("Independent singles, men") +mean dU_c_0negative if sample_0==1 &temp_choicehh==1 +putexcel B10=matrix(e(b)') +mean dU_c_1negative if sample_1==1 &temp_choicehh==1 +putexcel B11=matrix(e(b)') + +putexcel A15=("% obs with negative marginal utility wrt leisure") +putexcel A16=("Independent singles, women") +putexcel A17=("Independent singles, men") +mean dU_lei_0negative if sample_0==1 &temp_choicehh==1 +putexcel B16=matrix(e(b)') +mean dU_lei_1negative if sample_1==1 &temp_choicehh==1 +putexcel B17=matrix(e(b)') + + +//log likelihood +putexcel A22=("Log likelihood") +putexcel A23=("Independent singles, women") +putexcel A24=("Independent singles, men") + +qui mean ll_0 if sample_0==1 +putexcel B23=matrix(e(b)') +qui mean ll_1 if sample_1==1 +putexcel B24=matrix(e(b)') + + +//obs vs predicted wages fit +putexcel A28=("Mean hours") +putexcel A29=("Independent singles, women") +putexcel A30=("observed") +putexcel A31=("predicted") +putexcel A32=("Independent singles, men") +putexcel A33=("observed") +putexcel A34=("predicted") + + +qui mean lhw if temp_choice==1 & sample_0==1 +putexcel B30=matrix(e(b)') +qui mean temp_pred_lhw_0 if temp_choice==1 & sample_0==1 +putexcel B31=matrix(e(b)') + +qui mean lhw if temp_choice==1 & sample_1==1 +putexcel B33=matrix(e(b)') +qui mean temp_pred_lhw_1 if temp_choice==1 & sample_1==1 +putexcel B34=matrix(e(b)') + + +log close diff --git a/input_processing/labour_supply/do-files/model specifications/4b-singles_dep_elast-std model - final.do b/input_processing/labour_supply/do-files/model specifications/4b-singles_dep_elast-std model - final.do new file mode 100644 index 0000000..ed3b67d --- /dev/null +++ b/input_processing/labour_supply/do-files/model specifications/4b-singles_dep_elast-std model - final.do @@ -0,0 +1,416 @@ +************************************************************************ +* EU SILC (PL_2019_b3) +* Labour supply estimation for dependent singles +************************************************************************ +/* +// @@@ SPECIFICATION @@@ +Consumption-leisure preferences using a quadratic utility function with fixed costs. +Combined model for men and women with fixed cost interacted with gender, using predicted wages for everyone +*/ + +global file_log="${log}/singles_indep_elast-std-simple" +global n_choices = 4 // 4 choices: no work, plus 3 hours brackets. +global n_draws=100 //modify when computing elasticity 100 + + +cd "$local_data" + +*Housekeeping +capture log close +*office PC + +log using "$file_log", replace +pwd +clear all +set seed 1 //same seed gives same results + +*version 15 + +*======================================================================= +* estimate hours of work for female and male, respectively +*======================================================================= +//use wage 1 only because MU is better +use singles_dep_wage$impmethod, clear +//foreach gender in 0 1{ //loop begin for gender +capture drop temp_pred_lhw1 +capture drop pred_prob +capture drop pred_utility +capture drop pred_utility2 +capture drop max_utility2 +capture drop pred_choice2 +capture drop pred_lhw2 +capture drop temp_pred_lhw2 +capture drop epsilon2 + +capture drop pred_choice1 +capture drop pred_utility1 +capture drop max_utility1 +capture drop pred_choice1 +capture drop pred_lhw1 +capture drop temp_pred_lhw1 + + +drop if sim_flag==1 //make sure the data is actual at this point + + +global vars "hhcon_100 hhcon2_10000 leisure leisure2 lei_hhcon_100 hrs_40plus_dgn" //fixc_dgn adding fixed_cost#gender dummy +**************************************************************************************************************** +//clogit temp_choicehh `vars_simple', group (temp_idorigperson2) //estimate only on actual data (sim_flag==0) +asclogit temp_choicehh ${vars}, case(temp_idorigperson2) alt(temp_seq) casevars(liwwh liwwh2) nocons +**************************************************************************************************************** + +gen ll = (e(ll)) //gen log likelyhood + +eststo singles_wage$impmethod +gen sample=(e(sample)) + +//version 13 + +foreach gender in 0 1{ //loop begin for gender +////////////////////////////////////// +//output estimated results to Excel // +////////////////////////////////////// +* output labels +if (`gender' == 0){ +putexcel set "$results/reg_labourSupplyUtility_PL", sheet("SingleDep_Females") modify + +putexcel A1 = "REGRESSOR" +putexcel A2 = "IncomeDiv100" +putexcel A3 = "IncomeSqDiv10000" +putexcel A4 = "FemaleLeisure" +putexcel A5 = "FemaleLeisureSq" +putexcel A6 = "FemaleLeisure_IncomeDiv100" +putexcel A7 = "Hrs_40plus_Female" +putexcel A8 = "Liwwh_Female_1" +putexcel A9 = "LiwwhSq_Female_1" +putexcel A10 = "Liwwh_Female_2" +putexcel A11 = "LiwwhSq_Female_2" +putexcel A12 = "Liwwh_Female_3" +putexcel A13 = "LiwwhSq_Female_3" +putexcel A14 = "Liwwh_Female_10" +putexcel A15 = "LiwwhSq_Female_10" +putexcel A16 = "Liwwh_Female_20" +putexcel A17 = "LiwwhSq_Female_20" +putexcel A18 = "Liwwh_Female_30" +putexcel A19 = "LiwwhSq_Female_30" + +putexcel B1 = "COEFFICIENT" +putexcel C1 = "IncomeDiv100" +putexcel D1 = "IncomeSqDiv10000" +putexcel E1 = "FemaleLeisure" +putexcel F1 = "FemaleLeisureSq" +putexcel G1 = "FemaleLeisure_IncomeDiv100" +putexcel H1 = "Hrs_40plus_Female" +putexcel I1 = "Liwwh_Female_1" +putexcel J1 = "LiwwhSq_Female_1" +putexcel K1 = "Liwwh_Female_2" +putexcel L1 = "LiwwhSq_Female_2" +putexcel M1 = "Liwwh_Female_3" +putexcel N1 = "LiwwhSq_Female_3" +putexcel O1 = "Liwwh_Female_10" +putexcel P1 = "LiwwhSq_Female_10" +putexcel Q1 = "Liwwh_Female_20" +putexcel R1 = "LiwwhSq_Female_20" +putexcel S1 = "Liwwh_Female_30" +putexcel T1 = "LiwwhSq_Female_30" +} + +else{ +putexcel set "$results/reg_labourSupplyUtility_PL", sheet("SingleDep_Males") modify + +putexcel A1 = "REGRESSOR" +putexcel A2 = "IncomeDiv100" +putexcel A3 = "IncomeSqDiv10000" +putexcel A4 = "MaleLeisure" +putexcel A5 = "MaleLeisureSq" +putexcel A6 = "MaleLeisure_IncomeDiv100" +putexcel A7 = "Hrs_40plus_Male" +putexcel A8 = "Liwwh_Male_1" +putexcel A9 = "LiwwhSq_Male_1" +putexcel A10 = "Liwwh_Male_2" +putexcel A11 = "LiwwhSq_Male_2" +putexcel A12 = "Liwwh_Male_3" +putexcel A13 = "LiwwhSq_Male_3" +putexcel A14 = "Liwwh_Male_10" +putexcel A15 = "LiwwhSq_Male_10" +putexcel A16 = "Liwwh_Male_20" +putexcel A17 = "LiwwhSq_Male_20" +putexcel A18 = "Liwwh_Male_30" +putexcel A19 = "LiwwhSq_Male_30" + +putexcel B1 = "COEFFICIENT" +putexcel C1 = "IncomeDiv100" +putexcel D1 = "IncomeSqDiv10000" +putexcel E1 = "MaleLeisure" +putexcel F1 = "MaleLeisureSq" +putexcel G1 = "MaleLeisure_IncomeDiv100" +putexcel H1 = "Hrs_40plus_Male" +putexcel I1 = "Liwwh_Male_1" +putexcel J1 = "LiwwhSq_Male_1" +putexcel K1 = "Liwwh_Male_2" +putexcel L1 = "LiwwhSq_Male_2" +putexcel M1 = "Liwwh_Male_3" +putexcel N1 = "LiwwhSq_Male_3" +putexcel O1 = "Liwwh_Male_10" +putexcel P1 = "LiwwhSq_Male_10" +putexcel Q1 = "Liwwh_Male_20" +putexcel R1 = "LiwwhSq_Male_20" +putexcel S1 = "Liwwh_Male_30" +putexcel T1 = "LiwwhSq_Male_30" +} + +* output coefficients +matrix results = r(table) +matrix results = results[1..6,1...]' //extract the first six rows of results, and then transpose results +putexcel B2= matrix(results /*, names*/ ) //names nformat(number_d2) //write estimates in Excel from cell B2 + +* output variance-covariance matrix +matrix results=e(V) +putexcel C2 = matrix(results /*, names*/ ) //names nformat(number_d2) //write e(V) in Excel from cell C2 + +} //end of loop for gender + + +********************* +*Marginal utilities * +********************* +*this is inside the gender loop (ignore,estimates are combined for both genders) +capture drop dU_c +capture drop dU_lei +capture drop dU2_c +capture drop dU2_lei + + *----------------------------------------------------------------- + * First differential of utility w.r.t. disposable income + *----------------------------------------------------------------- + gen dU_c=_b[hhcon_100]+2*hhcon_100*_b[hhcon2_10000]+leisure*_b[lei_hhcon_100] + su dU_c if temp_choicehh==1 //& sim_flag==0 + + *----------------------------------------------------------------- + * Second differential of utility w.r.t. disposable income + *----------------------------------------------------------------- + gen dU2_c=2*_b[hhcon2_10000] + su dU2_c if temp_choicehh==1 //& sim_flag==0 + + *----------------------------------------------------------------- + * First differential of utility w.r.t. leisure + *----------------------------------------------------------------- + gen double dU_lei=_b[leisure]+2*leisure*_b[leisure2]+hhcon_100*_b[lei_hhcon_100] + su dU_lei if temp_choicehh==1 //& sim_flag==0 + + *----------------------------------------------------------------- + * Second differential of utility w.r.t. leisure + *----------------------------------------------------------------- + gen dU2_lei=2*_b[leisure2] + su dU2_lei if temp_choicehh==1 //& sim_flag==0 + + + +*----------------------------------------------------------------- +* Predict prob for both actual and simulated data +*----------------------------------------------------------------- +capture drop choice_prob +capture drop hrs_hat +capture drop E_hrs_hat +capture drop prob_work + +predict choice_prob //probability of a positive outcome +count +*the highest utility=deterministic+stochastic is chosen + +append using "sim_singles_dep_110_individuals_output_wage$impmethod" //for "singles" sample, get simulated ils_dispy resulting from 10% increase of gross wage +fre sim_flag +//we need to generate fixc_dgn also for the simulated income sample +replace fixc_dgn=fixed_cost*dgn if sim_flag==1 +lab var fixc_dgn "fixed cost for labour$\times$1(male)" + +predict double pred_prob if sim_flag==0 //predicted probabilities (deterministic) +predict double de_pred_utility if sim_flag==0, xb //deterministic component of utility +sum de_pred_utility if sim_flag==0 +//v15 update +predict double sim_pred_prob if sim_flag==1 //predicted probabilities (deterministic) +predict double sim_de_pred_utility if sim_flag==1, xb //for simulated hhcon, deterministic component of utility +su sim_de_pred_utility if sim_flag==1 + + + +capture drop hrs_elas_* +set seed 339487731 +//v15 update: loop for random draw +//add loop beginning +forvalues i = 1/$n_draws { +capture drop epsilon +capture drop pred_utility +capture drop max_utility +capture drop pred_lhw +capture drop temp_pred_lhw + +capture drop sim_pred_utility +capture drop sim_max_utility +capture drop sim_pred_lhw +capture drop sim_temp_pred_lhw + + +gen double epsilon= -log(-log(runiform())) //random draw from an extreme value distribution (required for counterfactual) +gen double pred_utility= de_pred_utility+epsilon if sim_flag==0 //utility=deterministic utility+stochastic utility + +bys temp_idorigperson2: egen double max_utility=max(pred_utility) if sim_flag==0 //for each agent highest utility +gen pred_lhw=lhw if max_utility==pred_utility & sim_flag==0 //predicted hours of work (only present in the chosen row) +replace pred_lhw=0 if pred_lhw==. +bys temp_idorigperson2: egen temp_pred_lhw=total(pred_lhw) , missing //expand pred_lhw2 to all alternatives (missing as 0) + + + +//v15 update: predict optimal hours for sim_hhcon +gen double sim_pred_utility= sim_de_pred_utility+epsilon if sim_flag==1 //utility=deterministic utility+stochastic utility +bys temp_idorigperson2: egen double sim_max_utility=max(sim_pred_utility) if sim_flag==1 //for each agent highest utility +gen sim_pred_lhw=lhw if sim_max_utility==sim_pred_utility & sim_flag==1 //predicted hours of work (only present in the chosen row) +bys temp_idorigperson2: egen sim_temp_pred_lhw=total(sim_pred_lhw) , missing //expand pred_lhw2 to all alternatives (missing as 0) + + +**************** +*Elasticities * +**************** +gen hrs_elas_`i'=10*(sim_temp_pred_lhw-temp_pred_lhw)/temp_pred_lhw if temp_choicehh==1 +} +order hrs_elas_*, last +egen mean_hrs_elas=rmean(hrs_elas_1-hrs_elas_$n_draws) if temp_choicehh==1 & sample==1 // single female's/male's hours elasticity (for each obs) +su mean_hrs_elas if temp_choicehh==1 & sample==1,d //summary of single females's hours elasticity across observations + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//hours fit graph (histograms for two genders)(with the last random draw as previous draws are all overwritten) // +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +twoway (histogram lhw if temp_choice==1 & sample==1, discrete percent color(green) ) /// + (histogram temp_pred_lhw if temp_choice==1 & sample==1, discrete percent fcolor(none) lcolor(black)), /// + legend(order(1 "observed" 2 "predicted" )) /// + subtitle("Couples, only one partner LS flexible") xtitle("weekly hours worked") xlabel(0 20 40 50, valuelabel ) + +//graph combine "his_hoursfit_0" "his_hoursfit_1" +graph export "$results_ls/singles-dep/his_hoursfit_bothgenders_dep.png", as(png) replace + + +///////////////////////// +//graph of elasticity // +///////////////////////// +twoway (histogram mean_hrs_elas if temp_choicehh==1 & sample==1 , fcolor(none) lcolor(black)), /// + subtitle("Hours elasticity") +graph export "$results_ls/singles-dep/hrs_elas_single_dep.png", as(png) replace + + +sum ils_dispy +//save singles_wage$impmethod.dta, replace //try not to save too many data files to save disc space + +/////////////////////////////// +//histogram of du/dc, du/dlei// +/////////////////////////////// +twoway (histogram dU_c if sample==1 &temp_choicehh==1 , fcolor(none) lcolor(black)), /// + subtitle("MU wrt income") + graph export "$results_ls/singles-dep/dUdc_single_dep.png", as(png) replace + +twoway (histogram dU_lei if sample==1& temp_choicehh==1, fcolor(none) lcolor(black)), /// + subtitle("MU wrt leisure") + graph export "$results_ls/singles-dep/dUdlei_single_dep.png", as(png) replace + + +su dU_c dU_lei dU2_c dU2_lei if sample==1& temp_choicehh==1 + + + +///////////////////////////////////// +//export estimation results to tex // +///////////////////////////////////// +esttab singles_wage$impmethod using "$results_ls/singles-dep/ls_single_dep_10.tex", replace label cells(b(star fmt(3))) stats(ll r2_p N ) nonumbers /// +collabels(none) /// +title(Labour supply (utility function) estimation: Couples, only one partner LS flexible. /// + Notes: Income in hundreds of British Pounds. /// +\label{tab:hours-singles}) /// +varlabels(r2_p pseudo-R^2) /// +addnote("*** Results significant at 0.1\%, ** 1\%, * 5\%.") //for writing tex including female and male(including at least three non-zero digits) + +esttab singles_wage$impmethod using "$results_ls/singles-dep/ls_single_dep_10.csv", replace label cells(b(star fmt(3))) stats(ll r2_p N ) nonumbers /// +collabels(none) /// +title(Labour supply (utility function) estimation: Couples, only one partner LS flexible. /// + Notes: Income in hundreds of British Pounds. /// +\label{tab:hours-singles}) /// +varlabels(r2_p pseudo-R^2) /// +addnote("*** Results significant at 0.1\%, ** 1\%, * 5\%.") //for writing csv including female and male(including at least three non-zero digits) + +///////////////////// +//Income deciles //// +///////////////////// +xtile dec_hhcon = hhcon if sample==1 &temp_choicehh==1, nq(10) //create decile variable for single female and male + +bysort dec_hhcon:su mean_hrs_elas if sample==1 &temp_choicehh==1 + +//box plot +label var dec_hhcon "income decile" +graph box mean_hrs_elas if temp_choicehh==1, ytitle(wage elasticity) over(dec_hhcon) subtitle("Couples, only one partner LS flexible") note("Income decile" /// +"Lines indicate upper adjacent value, 75th percentile, median, 25th percentile, lower adjacent value.") + +graph export "$results_ls/singles-dep/wage_elas_dep.png", as(png) replace + + +/////////////////// +///summary stats // +/////////////////// + +*percent of obs with positive marginal utilities +foreach i in dU_c dU_lei{ +//foreach gender in 0 1{ +gen `i'positive=(`i'>0) +su `i'positive if sample==1 & temp_choicehh==1 +//} +} +*percent of obs with negative marginal utilities +foreach i in dU_c dU_lei{ +cap drop `i'_negative +gen `i'_negative=(`i'<0) +sum `i'_negative if sample==1 & temp_choicehh==1 +} + + +/////////////////////////////////////////////// +//output to Excel file with summary stats /// +/////////////////////////////////////////////// +putexcel set "${summary_table}", sheet(${sheet}, replace) modify + + +putexcel A2=("Wage elasticities of hours of work") +putexcel A8=("Couples, only one LS flexible") +qui mean mean_hrs_elas if sample==1 &temp_choicehh==1 +putexcel B8=matrix(e(b)') + +putexcel A9=("% obs with negative marginal utility wrt income") +putexcel A14=("Couples, only one LS flexible") +qui mean dU_c_negative if sample==1 &temp_choicehh==1 +putexcel B14=matrix(e(b)') + + +putexcel A15=("% obs with negative marginal utility wrt leisure") +putexcel A21=("Couples, only one LS flexible") +qui mean dU_lei_negative if sample==1 &temp_choicehh==1 +putexcel B21=matrix(e(b)') + +//add log likelihood +putexcel A22=("Log likelihood") +putexcel A27=("Couples, only one LS flexible") +qui mean ll if sample==1 +putexcel B27=matrix(e(b)') + + +//obs vs predicted wages fit +putexcel A44=("Couples, only one LS flexible") +putexcel A45=("observed") +putexcel A46=("predicted") +qui mean lhw if temp_choice==1 & sample==1 +putexcel B45=matrix(e(b)') +qui mean temp_pred_lhw if temp_choice==1 & sample==1 +putexcel B46=matrix(e(b)') + + + +log close + + + diff --git a/input_processing/labour_supply/do-files/model specifications/4c-couples elast-std model - final.do b/input_processing/labour_supply/do-files/model specifications/4c-couples elast-std model - final.do new file mode 100644 index 0000000..dbbe0d5 --- /dev/null +++ b/input_processing/labour_supply/do-files/model specifications/4c-couples elast-std model - final.do @@ -0,0 +1,645 @@ +************************************************************************** +* EU SILC (PL_2019_b3) +* Labour supply estimation for couples +************************************************************************ +/* +// @@@ SPECIFICATION @@@ +Consumption-leisure preferences using a quadratic utility function with fixed costs. +One model for couples with men and women's fixed cost, using predicted wages for everyone +*/ + +global file_log="${log}/couples_elast-std-simple" +global n_choices = 4 // 4 choices: no work, plus 3 hours brackets. +global n_draws=100 //modify when computing elasticity100 + + + +*Housekeeping +capture log close + +log using "$file_log", replace +cd "$local_data" + +*======================================================================= +* estimate hours of work for couples with female and male partners +* Note: it is fine to use temp_idorigperson2 to be the couple's identifier +* as this is cross-sectional data and the partner does not vary +*======================================================================= +use couples_wage$impmethod, clear + + +global vars "hhcon_100 hhcon2_10000 leisure sp_leisure leisure2 sp_leisure2 lei_sp_lei lei_hhcon_100 sp_lei_hhcon_100 hrs_40plus sp_hrs_40plus" // fixed_cost sp_fixed_cost +************************************************************************************************************************************************ +//clogit temp_choicehh $vars , group (temp_idorigperson2) +asclogit temp_choicehh $vars, case(temp_idorigperson2) alt(temp_seq) casevar(liwwh liwwh2 sp_liwwh sp_liwwh2) nocons +************************************************************************************************************************************************* + +gen ll = (e(ll)) //gen log likelihood + +eststo couples_wage$impmethod +capture drop sample_couples +gen sample_couples=(e(sample)) + + +//version 13 + +////////////////////////////// +//output estimation results // +////////////////////////////// +* output labels +putexcel set "$results/reg_labourSupplyUtility_PL", sheet("Couples") modify +putexcel A1 = "REGRESSOR" +putexcel A2 = "IncomeDiv100" +putexcel A3 = "IncomeSqDiv10000" +putexcel A4 = "MaleLeisure" +putexcel A5 = "FemaleLeisure" +putexcel A6 = "MaleLeisureSq" +putexcel A7 = "FemaleLeisureSq" +putexcel A8 = "MaleLeisure_FemaleLeisure" +putexcel A9 = "MaleLeisure_IncomeDiv100" +putexcel A10 = "FemaleLeisure_IncomeDiv100" +putexcel A11 = "Hrs_40plus_Male" +putexcel A12 = "Hrs_40plus_Female" +putexcel A13 = "Liwwh_Male_1" +putexcel A14 = "LiwwhSq_Male_1" +putexcel A15 = "Liwwh_Female_1" +putexcel A16 = "LiwwhSq_Female_1" +putexcel A17 = "Liwwh_Male_2" +putexcel A18 = "LiwwhSq_Male_2" +putexcel A19 = "Liwwh_Female_2" +putexcel A20 = "LiwwhSq_Female_2" +putexcel A21 = "Liwwh_Male_3" +putexcel A22 = "LiwwhSq_Male_3" +putexcel A23 = "Liwwh_Female_3" +putexcel A24 = "LiwwhSq_Female_3" +putexcel A25 = "Liwwh_Male_10" +putexcel A26 = "LiwwhSq_Male_10" +putexcel A27 = "Liwwh_Female_10" +putexcel A28 = "LiwwhSq_Female_10" +putexcel A29 = "Liwwh_Male_11" +putexcel A30 = "LiwwhSq_Male_11" +putexcel A31 = "Liwwh_Female_11" +putexcel A32 = "LiwwhSq_Female_11" +putexcel A33 = "Liwwh_Male_12" +putexcel A34 = "LiwwhSq_Male_12" +putexcel A35 = "Liwwh_Female_12" +putexcel A36 = "LiwwhSq_Female_12" +putexcel A37 = "Liwwh_Male_13" +putexcel A38 = "LiwwhSq_Male_13" +putexcel A39 = "Liwwh_Female_13" +putexcel A40 = "LiwwhSq_Female_13" +putexcel A41 = "Liwwh_Male_20" +putexcel A42 = "LiwwhSq_Male_20" +putexcel A43 = "Liwwh_Female_20" +putexcel A44 = "LiwwhSq_Female_20" +putexcel A45 = "Liwwh_Male_21" +putexcel A46 = "LiwwhSq_Male_21" +putexcel A47 = "Liwwh_Female_21" +putexcel A48 = "LiwwhSq_Female_21" +putexcel A49 = "Liwwh_Male_22" +putexcel A50 = "LiwwhSq_Male_22" +putexcel A51 = "Liwwh_Female_22" +putexcel A52 = "LiwwhSq_Female_22" +putexcel A53 = "Liwwh_Male_23" +putexcel A54 = "LiwwhSq_Male_23" +putexcel A55 = "Liwwh_Female_23" +putexcel A56 = "LiwwhSq_Female_23" +putexcel A57 = "Liwwh_Male_30" +putexcel A58 = "LiwwhSq_Male_30" +putexcel A59 = "Liwwh_Female_30" +putexcel A60 = "LiwwhSq_Female_30" +putexcel A61 = "Liwwh_Male_31" +putexcel A62 = "LiwwhSq_Male_31" +putexcel A63 = "Liwwh_Female_31" +putexcel A64 = "LiwwhSq_Female_31" +putexcel A65 = "Liwwh_Male_32" +putexcel A66 = "LiwwhSq_Male_32" +putexcel A67 = "Liwwh_Female_32" +putexcel A68 = "LiwwhSq_Female_32" +putexcel A69 = "Liwwh_Male_33" +putexcel A70 = "LiwwhSq_Male_33" +putexcel A71 = "Liwwh_Female_33" +putexcel A72 = "LiwwhSq_Female_33" + +putexcel B1 = "COEFFICIENT" +putexcel C1 = "IncomeDiv100" +putexcel D1 = "IncomeSqDiv10000" +putexcel E1 = "MaleLeisure" +putexcel F1 = "FemaleLeisure" +putexcel G1 = "MaleLeisureSq" +putexcel H1 = "FemaleLeisureSq" +putexcel I1 = "MaleLeisure_FemaleLeisure" +putexcel J1 = "MaleLeisure_IncomeDiv100" +putexcel K1 = "FemaleLeisure_IncomeDiv100" +putexcel L1 = "Hrs_40plus_Male" +putexcel M1 = "Hrs_40plus_Female" +putexcel N1 = "Liwwh_Male_1" +putexcel O1 = "LiwwhSq_Male_1" +putexcel P1 = "Liwwh_Female_1" +putexcel Q1 = "LiwwhSq_Female_1" +putexcel R1 = "Liwwh_Male_2" +putexcel S1 = "LiwwhSq_Male_2" +putexcel T1 = "Liwwh_Female_2" +putexcel U1 = "LiwwhSq_Female_2" +putexcel V1 = "Liwwh_Male_3" +putexcel W1 = "LiwwhSq_Male_3" +putexcel X1 = "Liwwh_Female_3" +putexcel Y1 = "LiwwhSq_Female_3" +putexcel Z1 = "Liwwh_Male_10" +putexcel AA1 = "LiwwhSq_Male_10" +putexcel AB1 = "Liwwh_Female_10" +putexcel AC1 = "LiwwhSq_Female_10" +putexcel AD1 = "Liwwh_Male_11" +putexcel AE1 = "LiwwhSq_Male_11" +putexcel AF1 = "Liwwh_Female_11" +putexcel AG1 = "LiwwhSq_Female_11" +putexcel AH1 = "Liwwh_Male_12" +putexcel AI1 = "LiwwhSq_Male_12" +putexcel AJ1 = "Liwwh_Female_12" +putexcel AK1 = "LiwwhSq_Female_12" +putexcel AL1 = "Liwwh_Male_13" +putexcel AM1 = "LiwwhSq_Male_13" +putexcel AN1 = "Liwwh_Female_13" +putexcel AO1 = "LiwwhSq_Female_13" +putexcel AP1 = "Liwwh_Male_20" +putexcel AQ1 = "LiwwhSq_Male_20" +putexcel AR1 = "Liwwh_Female_20" +putexcel AS1 = "LiwwhSq_Female_20" +putexcel AT1 = "Liwwh_Male_21" +putexcel AU1 = "LiwwhSq_Male_21" +putexcel AV1 = "Liwwh_Female_21" +putexcel AW1 = "LiwwhSq_Female_21" +putexcel AX1 = "Liwwh_Male_22" +putexcel AY1 = "LiwwhSq_Male_22" +putexcel AZ1 = "Liwwh_Female_22" +putexcel BA1 = "LiwwhSq_Female_22" +putexcel BB1 = "Liwwh_Male_23" +putexcel BC1 = "LiwwhSq_Male_23" +putexcel BD1 = "Liwwh_Female_23" +putexcel BE1 = "LiwwhSq_Female_23" +putexcel BF1 = "Liwwh_Male_30" +putexcel BG1 = "LiwwhSq_Male_30" +putexcel BH1 = "Liwwh_Female_30" +putexcel BI1 = "LiwwhSq_Female_30" +putexcel BJ1 = "Liwwh_Male_31" +putexcel BK1 = "LiwwhSq_Male_31" +putexcel BL1 = "Liwwh_Female_31" +putexcel BM1 = "LiwwhSq_Female_31" +putexcel BN1 = "Liwwh_Male_32" +putexcel BO1 = "LiwwhSq_Male_32" +putexcel BP1 = "Liwwh_Female_32" +putexcel BQ1 = "LiwwhSq_Female_32" +putexcel BR1 = "Liwwh_Male_33" +putexcel BS1 = "LiwwhSq_Male_33" +putexcel BT1 = "Liwwh_Female_33" +putexcel BU1 = "LiwwhSq_Female_33" + +* output coefficients +matrix results = r(table) +matrix results = results[1..6,1...]' //extract the first six rows of results, and then transpose results +putexcel B2 = matrix(results /*, names*/ ) //names nformat(number_d2) //write in Excel from cell B2 + +* output variance-covariance matrix +matrix results=e(V) +putexcel C2 = matrix(results /*, names*/ ) //names nformat(number_d2) //write e(V) in Excel from cell C2 + + +****************** +*Predict choices * +****************** +*predictions from the model, we store epsilons required for counterfactuals and predicted probabilities +predict double pred_prob //predicted probabilities (deterministic) +predict double pred_utility , xb //deterministic component of utility +sum pred_utility + +/* +*method 1 +*the highest deterministic utility is chosen +bys temp_idorigperson2: egen double max_utility1=max(pred_utility) //for each agent var with highest utility +gen pred_choicehh1=(max_utility1==pred_utility) //dummy for predicted choices + +gen pred_lhw1=lhw if pred_choicehh1==1 //male predicted hours of work pred_lhw +gen pred_sp_lhw1=sp_lhw if pred_choicehh1==1 //female predicted hours of work pred_lhw + +bys temp_idorigperson2: egen temp_pred_lhw1=total(pred_lhw1) //expand pred_lhw to all alternatives +replace pred_lhw1=temp_pred_lhw1 //expand pred_lhw to all alternatives + +bys temp_idorigperson2: egen temp_pred_sp_lhw1=total(pred_sp_lhw1) //expand pred_sp_lhw to all alternatives +replace pred_sp_lhw1=temp_pred_sp_lhw1 //expand pred_sp_lhw to all alternatives +*/ + +*method 2 + +*the highest utility=deterministic+stochastic is chosen + +set seed 339487731 +gen double epsilon2= -log(-log(runiform())) //random draw from an extreme value distribution (required for counterfactual) +gen double pred_utility2= pred_utility+epsilon2 //utility=deterministic utility+stochastic utility +bys temp_idorigperson2: egen double max_utility2=max(pred_utility2) //for each agent highest utility +gen pred_choicehh2=(max_utility2==pred_utility2) //dummy for predicted choices + +gen pred_lhw2=lhw if pred_choicehh2==1 //male predicted hours of work +gen pred_sp_lhw2=sp_lhw if pred_choicehh2==1 //female predicted hours of work + +bys temp_idorigperson2: egen temp_pred_lhw2=total(pred_lhw2) //expand pred_lhw2 to all alternatives +replace pred_lhw2=temp_pred_lhw2 //expand pred_lhw2 to all alternatives + +bys temp_idorigperson2: egen temp_pred_sp_lhw2=total(pred_sp_lhw2) //expand pred_sp_lhw2 to all alternatives +replace pred_sp_lhw2=temp_pred_sp_lhw2 //expand pred_sp_lhw2 to all alternatives + + +**hours fit (histograms for two genders with 2 utility prediction methods) + + +*foreach j in 1 2{ //loop begin for utility prediction method + +///////////////////////////////// +///hours fit graph (histogram) // +///////////////////////////////// +twoway (histogram temp_hh_alt if temp_choicehh==1, xlabel(1/16, valuelabel noticks angle(45)) percent width(0.8) color(green)) /// + (histogram temp_hh_alt if pred_choicehh2==1, percent width(0.8) fcolor(none) lcolor(black)), /// + legend(order(1 "observed" 2 "predicted")) /// + subtitle("Couples, both LS flexible") note("(male hours, female hours)") + + +graph save "$results_ls/couples/his_hoursfit.gph", replace +graph export "$results_ls/couples/his_hoursfit_couples.png", as(png) replace + + + +*} //loop end for utility prediction method + +*method 1 +//tab pred_lhw1 lhw if temp_choicehh==1 , m //hours fit confusion matrix +//tab pred_sp_lhw1 sp_lhw if temp_choicehh==1 , m //hours fit confusion matrix + +*method 2 +//tab pred_lhw2 lhw if temp_choicehh==1 , m //hours fit confusion matrix +//tab pred_sp_lhw2 sp_lhw if temp_choicehh==1 , m //hours fit confusion matrix + + +sum ils_dispy hhcon +//save temp_file2_wage2.dta, replace + +/////////////////////////////////////// +//export estimation results to Excel // +/////////////////////////////////////// +//capture erase couples_lslogit.csv +//esttab couples_wage1 using couples_clogit.csv, replace label cells(b(star fmt(a3)) t(par fmt(2))) +esttab couples_wage$impmethod using "$results_ls/couples/ls_couples.tex", replace label cells(b(star fmt(3))) stats(ll r2_p N ) nonumbers /// +collabels(none) /// +title(Labour supply (utility function) estimation: Couples. /// + Notes: Income in hundreds of British Pounds. /// +\label{tab:hours-couples}) /// +varlabels(r2_p pseudo-R^2) /// +addnote("*** Results significant at 0.1\%, ** 1\%, * 5\%.") //for writing tex including female and male(including at least three non-zero digits) + + +esttab couples_wage$impmethod using "$results_ls/couples/ls_couples.csv", replace label cells(b(star fmt(3))) stats(ll r2_p N ) nonumbers /// +collabels(none) /// +title(Labour supply (utility function) estimation: Couples. /// + Notes: Income in hundreds of British Pounds. /// +\label{tab:hours-couples}) /// +varlabels(r2_p pseudo-R^2) /// +addnote("*** Results significant at 0.1\%, ** 1\%, * 5\%.") //for writing csv including female and male(including at least three non-zero digits) +///////////////////////////////////////////// + +********************* +*Marginal utilities * +********************* +capture drop dU_c +capture drop dU_lei* +capture drop dU2_c +capture drop dU2_lei* + + *----------------------------------------------------------------- + * First differential of utility w.r.t. disposable income + *----------------------------------------------------------------- + gen dU_c=_b[hhcon_100]+2*hhcon_100*_b[hhcon2_10000] +leisure*_b[lei_hhcon_100] +sp_leisure*_b[sp_lei_hhcon_100] + su dU_c if temp_choicehh==1 &e(sample) + + + *----------------------------------------------------------------- + * Second differential of utility w.r.t. disposable income + *----------------------------------------------------------------- + gen dU2_c=2*_b[hhcon2_10000] + su dU2_c if temp_choicehh==1 &e(sample) + + *----------------------------------------------------------------- + * First differential of utility w.r.t. leisure of male partner + *----------------------------------------------------------------- + gen double dU_lei_male =_b[leisure] +2*leisure *_b[leisure2] +hhcon_100*_b[lei_hhcon_100] + su dU_lei_male if temp_choicehh==1 &e(sample) + + *----------------------------------------------------------------- + * Second differential of utility w.r.t. leisure of male partner + *----------------------------------------------------------------- + gen dU2_lei_male=2*_b[leisure2] + su dU2_lei_male if temp_choicehh==1 &e(sample) + + + *----------------------------------------------------------------- + * First differential of utility w.r.t. leisure of female partner + *----------------------------------------------------------------- + gen double dU_lei_female=_b[sp_leisure]+2*sp_leisure*_b[sp_leisure2]+hhcon_100*_b[sp_lei_hhcon_100] + su dU_lei_female if temp_choicehh==1 &e(sample) + + *----------------------------------------------------------------- + * Second differential of utility w.r.t. leisure of female partner + *----------------------------------------------------------------- + gen dU2_lei_female=2*_b[sp_leisure2] + su dU2_lei_female if temp_choicehh==1 &e(sample) + + +*version 13 + +///////////////////////////////// +//summary stats for covariates // +///////////////////////////////// +tabstat $vars if e(sample) & temp_choicehh==1, stat(n mean sd min max) save +return list +matlist r(StatTotal) +matrix results = r(StatTotal)' +putexcel set "$results_ls/couples/couple_sum.xlsx", replace +putexcel B3 = matrix(results /*,names*/ ) +//display labels for vbls +local row = 4 +foreach x of varlist $vars { +describe `x' +local varlabel : var label `x' +putexcel A`row' = ("`varlabel'") +local row = `row'+1 +} + +//summary stats for vbls of interest +label variable lhw "male weekly hours of work" +label variable sp_lhw "female weekly hours of work" +label variable temp_d_deh_H "male high education (higher education; deh = 5-6)" +label variable temp_d_deh_M "male middle education (up to post secondary school; deh = 2-4)" +label variable temp_d_deh_L "male low education (up to lower secondary School; deh = 0-1)" +label variable sp_temp_d_deh_H "female high education (higher education; deh = 5-6)" +label variable sp_temp_d_deh_M "female middle education (up to post secondary school; deh = 2-4)" +label variable sp_temp_d_deh_L "female low education (up to lower secondary School; deh = 0-1)" +label variable hhcon "household disposable income" +label variable dag "male age" +label variable sp_dag "female age" +label variable fixed_cost "1(male works)" +label variable sp_fixed_cost "1(female works)" +global vars_long "hhcon lhw sp_lhw fixed_cost sp_fixed_cost dag sp_dag temp_mean_age temp_d_deh_L temp_d_deh_M temp_d_deh_H sp_temp_d_deh_L sp_temp_d_deh_M sp_temp_d_deh_H temp_n_ch* temp_d_ch* temp_region1-temp_region3" +tabstat $vars_long if e(sample) & temp_choicehh==1, stat(n mean sd min max) save +return list +matlist r(StatTotal) +matrix results = r(StatTotal)' +version 13 +putexcel set "$results_ls/couples/couple_sum2.xlsx", replace +putexcel A3 = matrix(results,names) +//display labels for vbls +local row = 4 +foreach x of varlist $vars_long { +describe `x' +local varlabel : var label `x' +putexcel A`row' = ("`varlabel'") //let the labels overwrite the names (making it B`row' can keep names) +local row = `row'+1 +} + + +*export estimation results to tex +//capture erase couples_lslogit.tex +esttab couples_wage$impmethod using "$results_ls/couples/couples_clogit.tex", replace label cells(b(star fmt(a3)) t(par fmt(2))) + + +**************** +*Elasticities * +**************** +*the highest utility=deterministic+stochastic is chosen +//firstly, append simulated hhcon resulting from an 10% increase of male partners' gross wage +append using "$local_data\sim_couples_110male_output_wage$impmethod" //get ils_dispy and hhcon resulting from 10% increase of male partners' gross wage +append using "$local_data\sim_couples_110female_output_wage$impmethod" //get sp_ils_dispy and hhcon resulting from 10% increase of female partners' gross wage +fre sim_flag + + +capture drop pred_prob +capture drop de_pred_utility +predict double pred_prob if sim_flag==0 //predicted probabilities (deterministic) +predict double de_pred_utility if sim_flag==0, xb //deterministic component of utility +sum de_pred_utility if sim_flag==0 +//v15 update +//combine the following gender loop with those below +foreach gender in 0 1{ //predict for simulated data, loop begin for gender (for own wage, cross wage elast) +capture drop pred_prob_`gender'wage +capture drop de_pred_utility_`gender'wage +predict double pred_prob_`gender'wage if sim_flag==1`gender' //predicted probabilities (deterministic) +predict double de_pred_utility_`gender'wage if sim_flag==1`gender', xb //for simulated hhcon, deterministic component of utility +su de_pred_utility_`gender'wage if sim_flag==1`gender' +//} + + +capture drop part_* +capture drop sim_part_* +capture drop in_* +capture drop out_* + +set seed 339487731 +//v15 update: loop for random draw +//add loop beginning +capture drop hrs_elas_`gender'wage* +capture drop sp_hrs_elas_`gender'wage* +capture drop mean_hrs_elas_`gender'wage +capture drop mean_sp_hrs_elas_`gender'wage + +forvalues i = 1/$n_draws { +capture drop epsilon +capture drop pred_utility +capture drop max_utility +capture drop pred_lhw +capture drop pred_sp_lhw +capture drop temp_pred_lhw +capture drop temp_pred_sp_lhw +*capture drop hrs_elas_`gender'wage_`i' +*capture drop sp_hrs_elas_`gender'wage_`i' + +gen double epsilon= -log(-log(runiform())) //random draw from an extreme value distribution (required for counterfactual) +gen double pred_utility= de_pred_utility+epsilon if sim_flag==0 //utility=deterministic utility+stochastic utility +//BUG! varlist not allowed +bys temp_idorigperson2: egen double max_utility=max(pred_utility) if sim_flag==0 //for each hh highest utility +//gen pred_choice2_`gender'=(max_utility2_`gender'==pred_utility2_`gender') //dummy for predicted choices +//gen pred_lhw2_`gender'=lhw if pred_choice2_`gender'==1& dgn==`gender' //predicted hours of work +gen pred_lhw=lhw if max_utility==pred_utility & sim_flag==0 & pred_utility!=. //predicted male partners' hours of work (only present in the chosen row) +gen pred_sp_lhw=sp_lhw if max_utility==pred_utility & sim_flag==0 & pred_utility!=. //predicted female partners' hours of work (only present in the chosen row) + +//replace pred_lhw=0 if pred_lhw==. +//replace pred_sp_lhw=0 if pred_sp_lhw==. + +bys temp_idorigperson2: egen temp_pred_lhw=total(pred_lhw) , missing //expand pred_lhw to all alternatives (missing as 0) +bys temp_idorigperson2: egen temp_pred_sp_lhw=total(pred_sp_lhw) , missing //expand pred_sp_lhw to all alternatives (missing as 0) + +*replace pred_lhw_0=temp_pred_lhw_0 & pred_lhw_0==. //expand pred_lhw to all alternatives + +capture drop pred_utility_`gender'wage +capture drop max_utility_`gender'wage +capture drop pred_lhw_`gender'wage +capture drop temp_pred_lhw_`gender'wage +capture drop pred_sp_lhw_`gender'wage +capture drop temp_pred_sp_lhw_`gender'wage + +//v15 update: predict optimal hours for sim_hhcon +gen double pred_utility_`gender'wage= de_pred_utility_`gender'wage+epsilon if sim_flag==1`gender' //utility=deterministic utility+stochastic utility +bys temp_idorigperson2: egen double max_utility_`gender'wage=max(pred_utility_`gender'wage) if sim_flag==1`gender' //for each agent highest utility +//gen pred_choice2_`gender'=(max_utility2_`gender'==pred_utility2_`gender') //dummy for predicted choices +//gen pred_lhw2_`gender'=lhw if pred_choice2_`gender'==1& dgn==`gender' //predicted hours of work +gen pred_lhw_`gender'wage=lhw if max_utility_`gender'wage==pred_utility_`gender'wage & sim_flag==1`gender' & pred_utility_`gender'wage!=. //predicted hours of work (only present in the chosen row) +gen pred_sp_lhw_`gender'wage=sp_lhw if max_utility_`gender'wage==pred_utility_`gender'wage & sim_flag==1`gender' & pred_utility_`gender'wage!=. //predicted hours of work (only present in the chosen row) + +bys temp_idorigperson2: egen temp_pred_lhw_`gender'wage=total(pred_lhw_`gender'wage) , missing //expand pred_lhw to all alternatives (missing as 0) +bys temp_idorigperson2: egen temp_pred_sp_lhw_`gender'wage=total(pred_sp_lhw_`gender'wage) , missing //expand pred_lhw to all alternatives (missing as 0) + +*elasticity +gen hrs_elas_`gender'wage_`i'=10*(temp_pred_lhw_`gender'wage-temp_pred_lhw)/temp_pred_lhw if temp_choicehh==1 +gen sp_hrs_elas_`gender'wage_`i'=10*(temp_pred_sp_lhw_`gender'wage-temp_pred_sp_lhw)/temp_pred_sp_lhw if temp_choicehh==1 +//male partner participation +gen part_`gender'wage_`i'=(temp_pred_lhw>0) if temp_choicehh==1 //dummy of participation (positive working hours) +gen sim_part_`gender'wage_`i'=(temp_pred_lhw_`gender'wage>0) if temp_choicehh==1 //simulated dummy of participation (positive working hours) +gen in_`gender'wage_`i'= (sim_part_`gender'wage_`i'-part_`gender'wage_`i'==1) if temp_choicehh==1 //dummy of switching from 0 hrs to positive hrs due to an increase of gross wage +drop sim_part_`gender'wage_`i' part_`gender'wage_`i' //save space for Stata +//gen out_`gender'wage_`i'= (sim_part_`gender'wage_`i'-part_`gender'wage_`i'==-1) if temp_choicehh==1 //dummy of switching from positive hrs to 0 hrs due to an increase of gross wage + +//female partner participation +gen sp_part_`gender'wage_`i'=(temp_pred_sp_lhw>0) if temp_choicehh==1 //dummy of participation (positive working hours) +gen sp_sim_part_`gender'wage_`i'=(temp_pred_sp_lhw_`gender'wage>0) if temp_choicehh==1 //simulated dummy of participation (positive working hours) +gen sp_in_`gender'wage_`i'= (sp_sim_part_`gender'wage_`i'-sp_part_`gender'wage_`i'==1) if temp_choicehh==1 //dummy of switching from 0 hrs to positive hrs due to an increase of gross wage +drop sp_sim_part_`gender'wage_`i' sp_part_`gender'wage_`i' //save space for Stata +//gen sp_out_`gender'wage_`i'= (sp_sim_part_`gender'wage_`i'-sp_part_`gender'wage_`i'==-1) if temp_choicehh==1 //dummy of switching from positive hrs to 0 hrs due to an increase of gross wage + + +} //loop end for random draw + +*Elastisities +order hrs_elas_`gender'wage_*, last +egen mean_hrs_elas_`gender'wage=rmean(hrs_elas_`gender'wage_1-hrs_elas_`gender'wage_$n_draws) if temp_choicehh==1 & sample_couples==1 // male partners' own wage and cross wage hours elasticity (for each obs) + +order sp_hrs_elas_`gender'wage_*, last +egen sp_mean_hrs_elas_`gender'wage=rmean(sp_hrs_elas_`gender'wage_1-sp_hrs_elas_`gender'wage_$n_draws) if temp_choicehh==1 & sample_couples==1 // male partners' own wage and cross wage hours elasticity (for each obs) + +su mean_hrs_elas_`gender'wage if temp_choicehh==1 & sample_couples==1,d //summary of ale partners' own wage and cross wage hours elasticity across observations +su sp_mean_hrs_elas_`gender'wage if temp_choicehh==1 & sample_couples==1,d //summary of ale partners' own wage and cross wage hours elasticity across observations + +} //loop end for gender + + +///////////////////////////////////////// +//graph of elasticity for both genders // +///////////////////////////////////////// +twoway (histogram mean_hrs_elas_0wage if temp_choicehh==1 & sample_couples==1 , color(green) ) /// + (histogram mean_hrs_elas_1wage if temp_choicehh==1 & sample_couples==1, /// + fcolor(none) lcolor(black)), legend(order(1 "female" 2 "male" )) /// + subtitle("Hours elasticity") +graph export "$results_ls/couples/hrs_elas_couples.png", as(png) replace + + + +/////////////////////////////// +//histogram of du/dc, du/dlei// +/////////////////////////////// +histogram dU_c if temp_choicehh==1, fcolor(none) lcolor(black) subtitle("MU wrt income for couples") + graph export "$results_ls/couples/dUdc_couple.png", as(png) replace + +twoway (histogram dU_lei_female if temp_choicehh==1 , color(green) ) /// + (histogram dU_lei_male if dgn==1 & temp_choicehh==1, /// + fcolor(none) lcolor(black)), legend(order(1 "female in couple" 2 "male in couple" )) /// + subtitle("MU wrt leisure") + graph export "$results_ls/couples/dUdlei_couple.png", as(png) replace + + +su dU_c dU_lei_female dU_lei_male if e(sample) & temp_choicehh==1 +su dU2_c dU2_lei_female dU2_lei_male if e(sample) & temp_choicehh==1 + + +/////////////////// +//Income deciles // +/////////////////// +xtile dec_hhcon = hhcon if sample_couples==1 &temp_choicehh==1, nq(10) //create decile variable +//own wage elasticity by decile +graph box mean_hrs_elas_1wage sp_mean_hrs_elas_0wage if temp_choicehh==1, ytitle(own wage elasticity) over(dec_hhcon) note("Income decile" /// +"Lines indicate upper adjacent value, 75th percentile, median, 25th percentile, lower adjacent value.") /// +subtitle("Couples, both LS flexible") legend(order(1 "male partner" 2 "female partner" )) +//graph export own_wage_elas.png, as(png) replace +graph export "$results_ls/couples/wage_elas_couples.png", as(png) replace + +//cross wage elasticity by decile +graph box mean_hrs_elas_0wage sp_mean_hrs_elas_1wage, ytitle(cross wage elasticity) over(dec_hhcon) /// +subtitle("cross wage elasticity by income decile") legend(order(1 "male partner" 2 "female partner" )) +graph export "$results_ls/couples/cross_wage_elas.png", as(png) replace + + +/////////////////// +///summary stats // +/////////////////// +*percent of obs with posititive marginal utilities +foreach i in dU_c dU_lei_male dU_lei_female{ +gen `i'_positive=(`i'>0) +su `i'_positive if e(sample) & temp_choicehh==1 +} +*percent of obs with negative marginal utilities +foreach i in dU_c dU_lei_male dU_lei_female { +cap drop `i'_negative +gen `i'_negative=(`i'<0) +sum `i'_negative if sample==1 & temp_choicehh==1 +} + +///////////////////////////////////////////// +//output to Excel file with summary stats /// +///////////////////////////////////////////// +putexcel set "${summary_table}", sheet(${sheet}, replace) modify + +putexcel A2=("Wage elasticities of hours of work") +putexcel A6=("Couples both LS flexible, women") +putexcel A7=("Couples both LS flexible, men") +mean mean_hrs_elas_0wage if temp_choicehh==1 & sample_couples==1 +putexcel B6=matrix(e(b)') +mean mean_hrs_elas_1wage if temp_choicehh==1 & sample_couples==1 +putexcel B7=matrix(e(b)') + +putexcel A9=("% obs with negative marginal utility wrt income") +putexcel A13=("Couples both LS flexible, men and women") +mean dU_c_negative if sample==1 & temp_choicehh==1 +putexcel B13=matrix(e(b)') + +putexcel A15=("% obs with negative marginal utility wrt leisure") +putexcel A19=("Couples, male partner") +putexcel A20=("Couples, female partner") +mean dU_lei_male_negative if sample==1 & temp_choicehh==1 +putexcel B19=matrix(e(b)') +mean dU_lei_female_negative if sample==1 & temp_choicehh==1 +putexcel B20=matrix(e(b)') + + +*log likelihood +putexcel A22=("Log likelihood") +putexcel A26=("Couples both LS flexible, men and women") +qui mean ll if sample==1 +putexcel B26=matrix(e(b)') + + +//obs vs predicted wages fit +putexcel A28=("Mean hours") + +putexcel A38=("Couples both LS flexible, men") +putexcel A39=("observed") +putexcel A40=("predicted") +qui mean lhw if temp_choicehh==1 +putexcel B39=matrix(e(b)') +qui mean lhw if pred_choicehh2==1 +putexcel B40=matrix(e(b)') + +putexcel A41=("Couples both LS flexible, women") +putexcel A42=("observed") +putexcel A43=("predicted") +qui mean sp_lhw if temp_choicehh==1 +putexcel B42=matrix(e(b)') +qui mean sp_lhw if pred_choicehh2==1 +putexcel B43=matrix(e(b)') + + +log close + + diff --git a/input_processing/labour_supply/do-files/model specifications/4d-singles_indep_elast-adult_ch - final.do b/input_processing/labour_supply/do-files/model specifications/4d-singles_indep_elast-adult_ch - final.do new file mode 100644 index 0000000..9438de8 --- /dev/null +++ b/input_processing/labour_supply/do-files/model specifications/4d-singles_indep_elast-adult_ch - final.do @@ -0,0 +1,390 @@ +******************************************************************************************** +* EU SILC (PL_2019_b3) +* Labour supply estimation for single adult children +******************************************************************************************** +/* +// @@@ SPECIFICATION @@@ +Consumption-leisure preferences using a quadratic utility function with fixed costs. +Combined model for men and women, using predicted wages for everyone +*/ + +global file_log="${log}/singles_elast_indep-adult_ch-simple" +global n_choices = 4 // 4 choices: no work, plus 4 hours brackets. +global n_draws=100 //modify when computing elasticity + +cd "$local_data" + +*Housekeeping +capture log close +*office PC + +log using "$file_log", replace +pwd +clear all +set seed 1 //same seed gives same results + +*version 15 + +*======================================================================= +* estimate hours of work for female and male, respectively +*======================================================================= + +use "singles_indep_wage$impmethod-dropped_sample",clear +capture drop temp_pred_lhw1 +capture drop pred_prob +capture drop pred_utility +capture drop pred_utility2 +capture drop max_utility2 +capture drop pred_choice2 +capture drop pred_lhw2 +capture drop temp_pred_lhw2 +capture drop epsilon2 + +capture drop pred_choice1 +capture drop pred_utility1 +capture drop max_utility1 +capture drop pred_choice1 +capture drop pred_lhw1 +capture drop temp_pred_lhw1 + + +drop if sim_flag==1 //make sure the data is actual at this point + +global vars "hhcon_100 hhcon2_10000 leisure leisure2 lei_hhcon_100 hrs_40plus_dgn" //fixc_dgn adding fixed_cost#gender dummy +************************************************************************************************************************************ +//clogit temp_choicehh `vars_simple', group (temp_idorigperson2) //estimate only on actual data (sim_flag==0),only for adult children +asclogit temp_choicehh $vars, case(temp_idorigperson2) alt(temp_seq) casevars(liwwh liwwh2) nocons +************************************************************************************************************************************ + +gen ll=(e(ll)) //predict log likelihood + +eststo singles_wage$impmethod +gen sample=(e(sample)) + +//version 13 + +foreach gender in 0 1{ //loop begin for gender +////////////////////////////////////// +//output estimated results to Excel // +////////////////////////////////////// +* output labels +if (`gender' == 0){ +putexcel set "$results/reg_labourSupplyUtility_PL", sheet("SingleAC_Females") modify + +putexcel A1 = "REGRESSOR" +putexcel A2 = "IncomeDiv100" +putexcel A3 = "IncomeSqDiv10000" +putexcel A4 = "FemaleLeisure" +putexcel A5 = "FemaleLeisureSq" +putexcel A6 = "FemaleLeisure_IncomeDiv100" +putexcel A7 = "Hrs_40plus_Female" +putexcel A8 = "Liwwh_Female_1" +putexcel A9 = "LiwwhSq_Female_1" +putexcel A10 = "Liwwh_Female_2" +putexcel A11 = "LiwwhSq_Female_2" +putexcel A12 = "Liwwh_Female_3" +putexcel A13 = "LiwwhSq_Female_3" +putexcel A14 = "Liwwh_Female_10" +putexcel A15 = "LiwwhSq_Female_10" +putexcel A16 = "Liwwh_Female_20" +putexcel A17 = "LiwwhSq_Female_20" +putexcel A18 = "Liwwh_Female_30" +putexcel A19 = "LiwwhSq_Female_30" + +putexcel B1 = "COEFFICIENT" +putexcel C1 = "IncomeDiv100" +putexcel D1 = "IncomeSqDiv10000" +putexcel E1 = "FemaleLeisure" +putexcel F1 = "FemaleLeisureSq" +putexcel G1 = "FemaleLeisure_IncomeDiv100" +putexcel H1 = "Hrs_40plus_Female" +putexcel I1 = "Liwwh_Female_1" +putexcel J1 = "LiwwhSq_Female_1" +putexcel K1 = "Liwwh_Female_2" +putexcel L1 = "LiwwhSq_Female_2" +putexcel M1 = "Liwwh_Female_3" +putexcel N1 = "LiwwhSq_Female_3" +putexcel O1 = "Liwwh_Female_10" +putexcel P1 = "LiwwhSq_Female_10" +putexcel Q1 = "Liwwh_Female_20" +putexcel R1 = "LiwwhSq_Female_20" +putexcel S1 = "Liwwh_Female_30" +putexcel T1 = "LiwwhSq_Female_30" +} + +else{ +putexcel set "$results/reg_labourSupplyUtility_PL", sheet("SingleAC_Males") modify + +putexcel A1 = "REGRESSOR" +putexcel A2 = "IncomeDiv100" +putexcel A3 = "IncomeSqDiv10000" +putexcel A4 = "MaleLeisure" +putexcel A5 = "MaleLeisureSq" +putexcel A6 = "MaleLeisure_IncomeDiv100" +putexcel A7 = "Hrs_40plus_Male" +putexcel A8 = "Liwwh_Male_1" +putexcel A9 = "LiwwhSq_Male_1" +putexcel A10 = "Liwwh_Male_2" +putexcel A11 = "LiwwhSq_Male_2" +putexcel A12 = "Liwwh_Male_3" +putexcel A13 = "LiwwhSq_Male_3" +putexcel A14 = "Liwwh_Male_10" +putexcel A15 = "LiwwhSq_Male_10" +putexcel A16 = "Liwwh_Male_20" +putexcel A17 = "LiwwhSq_Male_20" +putexcel A18 = "Liwwh_Male_30" +putexcel A19 = "LiwwhSq_Male_30" + +putexcel B1 = "COEFFICIENT" +putexcel C1 = "IncomeDiv100" +putexcel D1 = "IncomeSqDiv10000" +putexcel E1 = "MaleLeisure" +putexcel F1 = "MaleLeisureSq" +putexcel G1 = "MaleLeisure_IncomeDiv100" +putexcel H1 = "Hrs_40plus_Male" +putexcel I1 = "Liwwh_Male_1" +putexcel J1 = "LiwwhSq_Male_1" +putexcel K1 = "Liwwh_Male_2" +putexcel L1 = "LiwwhSq_Male_2" +putexcel M1 = "Liwwh_Male_3" +putexcel N1 = "LiwwhSq_Male_3" +putexcel O1 = "Liwwh_Male_10" +putexcel P1 = "LiwwhSq_Male_10" +putexcel Q1 = "Liwwh_Male_20" +putexcel R1 = "LiwwhSq_Male_20" +putexcel S1 = "Liwwh_Male_30" +putexcel T1 = "LiwwhSq_Male_30" +} + +* output coefficients +matrix results = r(table) +matrix results = results[1..6,1...]' //extract the first six rows of results, and then transpose results +putexcel B2= matrix(results /*, names*/ ) //names nformat(number_d2) //write estimates in Excel from cell B2 + +* output variance-covariance matrix +matrix results=e(V) +putexcel C2 = matrix(results /*, names*/ ) //names nformat(number_d2) //write e(V) in Excel from cell C2 + +} //end of loop for gender + +********************* +*Marginal utilities * +********************* +capture drop dU_c +capture drop dU_lei +capture drop dU2_c +capture drop dU2_lei + + *----------------------------------------------------------------- + * First differential of utility w.r.t. disposable income + *----------------------------------------------------------------- + gen dU_c=_b[hhcon_100]+2*hhcon_100*_b[hhcon2_10000] +leisure*_b[lei_hhcon_100] + su dU_c if temp_choicehh==1 //& sim_flag==0 + + *----------------------------------------------------------------- + * Second differential of utility w.r.t. disposable income + *----------------------------------------------------------------- + gen dU2_c=2*_b[hhcon2_10000] + su dU2_c if temp_choicehh==1 //& sim_flag==0 + + *----------------------------------------------------------------- + * First differential of utility w.r.t. leisure + *----------------------------------------------------------------- + gen double dU_lei=_b[leisure]+2*leisure*_b[leisure2]+hhcon_100*_b[lei_hhcon_100] + su dU_lei if temp_choicehh==1 //& sim_flag==0 + + *----------------------------------------------------------------- + * Second differential of utility w.r.t. leisure + *----------------------------------------------------------------- + gen dU2_lei=2*_b[leisure2] + su dU2_lei if temp_choicehh==1 //& sim_flag==0 + +*----------------------------------------------------------------- +* Predict prob for both actual and simulated data +*----------------------------------------------------------------- +capture drop choice_prob +capture drop hrs_hat +capture drop E_hrs_hat +capture drop prob_work + +predict choice_prob //probability of a positive outcome + + +*the highest utility=deterministic+stochastic is chosen + +append using "sim_singles_indep_110_individuals_output_wage$impmethod-dropped_sample" //for "singles" sample, get simulated ils_dispy resulting from 10% increase of gross wage +predict double pred_prob if sim_flag==0 //predicted probabilities (deterministic) +predict double de_pred_utility if sim_flag==0, xb //deterministic component of utility +sum de_pred_utility if sim_flag==0 +//v15 update +predict double sim_pred_prob if sim_flag==1 //predicted probabilities (deterministic) + +predict double sim_de_pred_utility if sim_flag==1, xb //for simulated hhcon, deterministic component of utility +su sim_de_pred_utility if sim_flag==1 + + +capture drop hrs_elas_* +set seed 339487731 +//v15 update: loop for random draw +//add loop beginning +forvalues i = 1/$n_draws { +capture drop epsilon +capture drop pred_utility +capture drop max_utility +capture drop pred_lhw +capture drop temp_pred_lhw + +capture drop sim_pred_utility +capture drop sim_max_utility +capture drop sim_pred_lhw +capture drop sim_temp_pred_lhw + + +gen double epsilon= -log(-log(runiform())) //random draw from an extreme value distribution (required for counterfactual) +gen double pred_utility= de_pred_utility+epsilon if sim_flag==0 //utility=deterministic utility+stochastic utility + +bys temp_idorigperson2: egen double max_utility=max(pred_utility) if sim_flag==0 //for each agent highest utility +gen pred_lhw=lhw if max_utility==pred_utility & sim_flag==0 //predicted hours of work (only present in the chosen row) +replace pred_lhw=0 if pred_lhw==. +bys temp_idorigperson2: egen temp_pred_lhw=total(pred_lhw) , missing //expand pred_lhw2 to all alternatives (missing as 0) + + + +//v15 update: predict optimal hours for sim_hhcon +gen double sim_pred_utility= sim_de_pred_utility+epsilon if sim_flag==1 //utility=deterministic utility+stochastic utility +bys temp_idorigperson2: egen double sim_max_utility=max(sim_pred_utility) if sim_flag==1 //for each agent highest utility +gen sim_pred_lhw=lhw if sim_max_utility==sim_pred_utility & sim_flag==1 //predicted hours of work (only present in the chosen row) +bys temp_idorigperson2: egen sim_temp_pred_lhw=total(sim_pred_lhw) , missing //expand pred_lhw2 to all alternatives (missing as 0) + +*replace sim_pred_lhw=sim_temp_pred_lhw if dgn==`gender' & sim_pred_lhw==. //expand pred_lhw2 to all alternatives + + +*elasticity +gen hrs_elas_`i'=10*(sim_temp_pred_lhw-temp_pred_lhw)/temp_pred_lhw if temp_choicehh==1 +} + +order hrs_elas_*, last +egen mean_hrs_elas=rmean(hrs_elas_1-hrs_elas_$n_draws) if temp_choicehh==1 & sample==1 // single female's/male's hours elasticity (for each obs) +su mean_hrs_elas if temp_choicehh==1 & sample==1,d //summary of single females's hours elasticity across observations + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//hours fit graph (histograms for two genders)(with the last random draw as previous draws are all overwritten) +///////////////////////////////////////////////////////////////////////////////////////////////////////////////// +twoway (histogram lhw if temp_choice==1 & sample==1, discrete percent color(green) ) /// + (histogram temp_pred_lhw if temp_choice==1 & sample==1, discrete percent fcolor(none) lcolor(black)), /// + legend(order(1 "observed" 2 "predicted" )) /// + subtitle("Adult children, Men and Women") xtitle("weekly hours worked") xlabel(0 20 40 50, valuelabel ) +graph save "$results_ls/singles-adch/his_hoursfit_indep_adult_ch.gph", replace + +graph export "$results_ls/singles-adch/his_hoursfit_indep_adult_ch.png", as(png) replace + + +///////////////////////// +//graph of elasticity // +///////////////////////// +twoway (histogram mean_hrs_elas if temp_choicehh==1 & sample==1 , fcolor(none) lcolor(black)), /// + subtitle("Hours elasticity") +graph export "$results_ls/singles-adch/hrs_elas_indep_adult_ch.png", as(png) replace + + +/////////////////////////////// +//histogram of du/dc, du/dlei// +/////////////////////////////// +twoway (histogram dU_c if sample==1 &temp_choicehh==1 , fcolor(none) lcolor(black)), /// + subtitle("MU wrt income") + graph export "$results_ls/singles-adch/dUdc_indep_adult_ch.png", as(png) replace + +twoway (histogram dU_lei if sample==1& temp_choicehh==1, fcolor(none) lcolor(black)), /// + subtitle("MU wrt leisure") + graph export "$results_ls/singles-adch/dUdlei_indep_adult_ch.png", as(png) replace + + + +*export estimation results to Latex +esttab singles_wage$impmethod using "$results_ls/singles-adch/ls_single_indep_10-adult_ch.tex", replace label cells(b(star fmt(3))) stats(ll r2_p N ) nonumbers /// +collabels(none) /// +title(Labour supply (utility function) estimation: Adult children. /// + Notes: Income in hundreds of British Pounds. /// +\label{tab:hours-singles-adult_ch}) /// +varlabels(r2_p pseudo-R^2) /// +addnote("*** Results significant at 0.1\%, ** 1\%, * 5\%.") //for writing tex including female and male(including at least three non-zero digits) + +esttab singles_wage$impmethod using "$results_ls/singles-adch/ls_single_indep_10-adult_ch.csv", replace label cells(b(star fmt(3))) stats(ll r2_p N ) nonumbers /// +collabels(none) /// +title(Labour supply (utility function) estimation: Adult children. /// + Notes: Income in hundreds of British Pounds. /// +\label{tab:hours-singles-adult_ch}) /// +varlabels(r2_p pseudo-R^2) /// +addnote("*** Results significant at 0.1\%, ** 1\%, * 5\%.") //for writing csv including female and male(including at least three non-zero digits) + + +/////////////////////// +////Income deciles //// +/////////////////////// +xtile dec_hhcon = hhcon if sample==1 &temp_choicehh==1, nq(10) //create decile variable for single female and male +bysort dec_hhcon:su mean_hrs_elas if sample==1 &temp_choicehh==1 + +//box plot +graph box mean_hrs_elas if temp_choicehh==1, ytitle(wage elasticity) over(dec_hhcon) note("Income decile" /// +"Lines indicate upper adjacent value, 75th percentile, median, 25th percentile, lower adjacent value.") /// + subtitle("Adult children, Men and Women") + graph export "$results_ls/singles-adch/wage_elas_indep_adult_ch.png", as(png) replace + + + +/////////////////// +///summary stats // +/////////////////// +*percent of obs with positive marginal utilities +foreach i in dU_c dU_lei{ +gen `i'positive=(`i'>0) +su `i'positive if sample==1 & temp_choicehh==1 +} +*percent of obs with negative marginal utilities +foreach i in dU_c dU_lei{ +cap drop `i'_negative +gen `i'_negative=(`i'<0) +sum `i'_negative if sample==1 & temp_choicehh==1 +} + +////////////////////////////////////////////// +//output to Excel file with summary stats//// +///////////////////////////////////////////// +putexcel set "${summary_table}", sheet(${sheet}, replace) modify + +putexcel A2=("Wage elasticities of hours of work") +putexcel A5=("Adult children") +mean mean_hrs_elas if temp_choicehh==1 & sample==1 +putexcel B5=matrix(e(b)') + + +putexcel A9=("% obs with negative marginal utility wrt income") +putexcel A12=("Adult children") +qui mean dU_c_negative if temp_choicehh==1 & sample==1 +putexcel B12=matrix(e(b)') + +putexcel A15=("% obs with negative marginal utility wrt leisure") +putexcel A18=("Adult children") +qui mean dU_lei_negative if temp_choicehh==1 & sample==1 +putexcel B18=matrix(e(b)') + +*log likelihood +putexcel A22=("Log likelihood") +putexcel A25=("Adult children") +qui mean ll if sample==1 +putexcel B25=matrix(e(b)') + + +//obs vs predicted wages fit +putexcel A35=("Adult children") +putexcel A36=("observed") +putexcel A37=("predicted") + +qui mean lhw if temp_choice==1 & sample==1 +putexcel B36=matrix(e(b)') +qui mean temp_pred_lhw if temp_choice==1 & sample==1 +putexcel B37=matrix(e(b)') + + +log close diff --git a/input_processing/labour_supply/do-files/std singles and couples data preparation/1-input and output data-std model.do b/input_processing/labour_supply/do-files/std singles and couples data preparation/1-input and output data-std model.do new file mode 100644 index 0000000..6636e5e --- /dev/null +++ b/input_processing/labour_supply/do-files/std singles and couples data preparation/1-input and output data-std model.do @@ -0,0 +1,3755 @@ +/************************************************************************************************** +* PROJECT: Poland EM Data (PL_2019_b3.txt) +* DO-FILE: Labour supply EUROMOD input and output data generation +* +* PURPOSE: +* - Prepare EUROMOD input/output data for labour supply estimation. +**************************************************************************************************/ + +/************************************************************************************************** +* FILE DESCRIPTION +************************************************************************************************** + +This .do file prepares data for labour supply estimation and generates EUROMOD input & output data. + +(1) Household composition adjustment +(2) Definition of temp_singles, temp_couples, temp_not_flexible +(3) Wage estimation using Heckman selectivity model; predicted wages assigned in two ways: + • wage1 – to everyone + • wage2 – only to non-workers +(4) Expansion to labour supply alternatives +(5) Benefit counterfactual allocation adjustments +(6) Run EUROMOD for disposable income +(7) Split sample for estimation: singles vs couples + +========================== +DATA FILTER – "SINGLES" +========================== +Singles are individuals who: +1. Have no partner (idpartner == 0), OR have a partner who is: + - a student, OR + - sick/disabled, OR + - outside working age (<16 or >75), OR + - a pensioner. +AND who themselves satisfy: +2. Working age (16 ≤ dag ≤ 75) +3. Not student (les != 6), not disabled/sick (les != 8), not pensioner (les != 4). + +========================== +DATA FILTER – "COUPLES" +========================== +Both partners satisfy the flexible worker conditions above. + +========================== +DATA FILTER – "NOT FLEXIBLE" +========================== +All individuals who are neither singles nor couples according to above definitions. + +--------------------------- +BENEFITS COUNTERFACTUALS +--------------------------- +ASSUMPTION #1: +For singles with student/disabled partners: partner’s benefits are held constant across choices. + +ASSUMPTION #2(A): +Simulated benefits – EUROMOD calculates correctly. + +ASSUMPTION #2(B1): +Not simulated, compatible with work, depend on YEM/LHW → set to zero. + +ASSUMPTION #2(B2): +Not simulated, NOT compatible with work, do not depend on YEM/LHW → set to observed amount. + +ASSUMPTION #2(B3): +Not simulated, NOT work-compatible, received in observed state → individual excluded from sample. + +--------------------------- +INCOME COUNTERFACTUALS +--------------------------- +Workers: assume income equals major source (yem or yse). +If yem == yse: use yem. +Non-workers: assume income = employed income. + +--------------------------- +WAGE IMPUTATION METHODS +--------------------------- +wage1 – predicted wages for everyone +wage2 – predicted wages only for non-workers +*/ + +global file_log "Input_output_data" + +/************************************************************************************************** +* IMPORT DATA +**************************************************************************************************/ + +cd "$local_data" +pwd + +capture log close +log using "$file_log", replace + +clear all +set seed 1 // ensure replicability across runs + +run "${do_files}/add_original_SILC_vars.do" + +// capture confirm file "$em_original/$file_input.txt" // original confirmation step (kept) +import delimited "$em_original/$file_input.txt", clear delim(tab) // import raw SILC-based file + +drop *_f // important! They will mess up the ls alternatives if not dropped here + +*======================================================================= +* CORRECT ANOMALIES +*======================================================================= + +// individuals aged < 18 in couples +tab dag if dag < 18 & idpartner > 0 +replace dag = 18 if dag < 18 & idpartner > 0 /* (3 real changes made) */ + // Ensures no minor is recorded as part of a couple + // (required for microsim consistency) + + +*---------------------------------------------------------------------------------------------------------------- +* NUMBER OF CHILDREN IN HOUSEHOLD & DUMMIES FOR CHILDREN BY AGE GROUP +*---------------------------------------------------------------------------------------------------------------- + +// RMK: these flag names do not follow convention but variables are then dropped +gen byte ch = (dag < 18) // child indicator, 0–17 inclusive +gen byte ch2 = (dag <= 2) // children aged 0–2 +gen byte ch6 = (dag >= 3 & dag <= 6) // children aged 3–6 +gen byte ch12 = (dag >= 7 & dag <= 12) // children aged 7–12 +gen byte ch17 = (dag >= 13 & dag <= 17) // children aged 13–17 + +sum ch* // check plausibility of distribution of flags + +sort idhh idperson +tempfile input // create temporary storage of current dataset +save `input' + + +foreach childgr of varlist ch* { + + noi di "Children age group: `childgr'", _newline + + keep if `childgr' == 1 // keep only children in this age group + keep idhh idmother idfather dag // keep identifiers and age for checks + + gen long temp_parent = idmother // assign idmother as primary parent + replace temp_parent = idfather if temp_parent==0 + // if mother missing, fallback to father + // !!! ISSUE: if both are 0 → temp_parent remains 0 + // This creates a pseudo-parent with id=0 + // Later dropped, but confirm intended behaviour. + + rename temp_parent idperson // parent becomes the “person” to whom child is assigned + + bysort idperson: gen int temp_n_`childgr' = _N // count children in this age group per parent + bysort idperson: gen int temp_d_`childgr' = (temp_n_`childgr' > 0) + // dummy: parent has ≥1 children in this group + + duplicates drop idperson, force // !!! FORCE deletes information without inspection + // Should check number dropped to avoid data loss + + drop dag idmother idfather // clean temporary dataset + sort idhh idperson + + merge m:1 idhh idperson using `input' // attach parent back to full dataset + + drop if _merge == 1 // drop rows created artificially (idperson==0) + // but check counts in case of unintended loss + drop _merge + + recode temp_n_`childgr' (. = 0) // set missing counts to zero + recode temp_d_`childgr' (. = 0) // set missing dummies to zero + + save `input', replace // update working dataset for next iteration + +} // foreach childgr + + +drop ch* // drop temporary raw child flags + +label variable temp_d_ch "1(children aged 0-17)" +label variable temp_d_ch2 "1(children aged 0-2)" +label variable temp_d_ch6 "1(children aged 3-6)" +label variable temp_d_ch12 "1(children aged 7-12)" +label variable temp_d_ch17 "1(children aged 13-17)" + +label variable temp_n_ch "number of children aged 0-17" +label variable temp_n_ch2 "number of children aged 0-2" +label variable temp_n_ch6 "number of children aged 3-6" +label variable temp_n_ch12 "number of children aged 7-12" +label variable temp_n_ch17 "number of children aged 13-17" + +sum temp_d_ch* temp_n_ch* // quick sanity check of result + + +*---------------------------------------------------------------------------------- +* ASSIGN TO EACH PARTNER THE SUM OF HIS/HER CHILDREN & PARTNER'S CHILDREN +* CREATE CHILDREN DUMMIES BY AGE GROUP +*---------------------------------------------------------------------------------- + +// Problem 1: children variables are attributed only to one parent +// Problem 2: partners might have different children variables + +// Attribute the same values of children variables to the partner +foreach var of varlist temp_n_ch* temp_d_ch* { + rename `var' partner_`var' // rename own child variables to partner_* to prepare for merge +} + +keep idhh idpartner partner_temp_n_ch* partner_temp_d_ch* +rename idpartner idperson // !!! Replaces idperson with partner’s id + // OK if idpartner=0 already dropped later +sort idhh idperson + +// Merge the new dataset with the old one. Now each person has values for own kids and partner's kids +merge m:1 idhh idperson using `input' + +drop if _merge == 1 // individuals without partner (idpartner==0) +drop _merge + + +foreach var of varlist temp_n_ch* temp_d_ch* { + + assert `var' != . // ensures own child vars have no missing + // !!! may break if a parent genuinely has missing parent link + + recode partner_`var' (. = 0) // partners without children get a zero + + replace `var' = `var' + partner_`var' // combine counts: own + partner's + // !!! POTENTIAL DOUBLE-COUNTING: + // if the dataset incorrectly lists a child twice, + // both parents might already have counted them +} + +drop partner_temp_n_ch* partner_temp_d_ch* + +egen test = rowtotal(temp_n_ch?*) // compute total children across age groups +noi di in y "Check number of children: these variables should be equal" +noi compare test temp_n_ch +assert test == temp_n_ch // ensures that age-specific counts sum to total +drop test + +assert temp_d_ch != . // ensures no missing in dummies + // !!! If dataset contains no children at all, + // this will still pass, but good to double check + + +*-------------------------------------------------------------------------------------------------------------------------- +* Economic status +* +*-------------------------------------------------------------------------------------------------------------------------- +label var les "economic status" +label define temp_lab_les 0 " 0 - Pre-school" 1 " 1 - Farmer" 2 "2 - Employer or self-employed" 3 "3 - Employee" /// +4 "4 - Pensioner" 5 "5 - Unemployed" 6 "6 - Student" 7 "7 - Inactive" 8 "8 - Sick or disabled" 9 "9 - Other" +label values les temp_lab_les + +*------------------------------------------------------------ +* Education +*------------------------------------------------------------ + +label define temp_lab_deh 0 "Not completed Primary" 1 "Primary" 2 "Lower Secondary" 3 "Upper Secondary" 4 "Post Secondary" 5 "Tertiary" +label values deh temp_lab_deh + +gen byte temp_d_deh_L = (deh == 0 | deh == 1) +label variable temp_d_deh_L "1(low education (up to lower secondary School; deh = 0-1))" +gen byte temp_d_deh_M = (deh == 2 | deh == 3 | deh == 4) +label variable temp_d_deh_M "1(middle education (up to post secondary school; deh = 2-4))" +gen byte temp_d_deh_H = (deh == 5) +label variable temp_d_deh_H "1(high education (tertiary school; deh = 5))" + +*-------------------------------------------------------------------------------------------------------------------------- +* Marital status +* +*-------------------------------------------------------------------------------------------------------------------------- +//DP: dms is useful to distinguish singles and previously partnered, otherwise living with a partner should prevail over civil status +label var dms "marital status" +label def lab_dms 1 "single" 2 "married" 3 "separated" 4 "divorced" 5 "widowed" +label val dms lab_dms +*marital status dummies +tab dms +gen partnered=(idpartner>0) +tab2 dms partnered + +//Single never married +gen temp_single=((dms==1) & idpartner==0) //define dummy of single +//gen temp_married=(dms==2) //define dummy of married (this is not useful when the target is singles) +//gen temp_separated=(dms==3) //define dummy of separated +//gen temp_divorced=(dms==4) //define dummy of divorced +//gen temp_widowed=(dms==5) //define dummy of widowed + +//labels +label variable temp_single "single" +//label variable temp_married "married" +//label variable temp_separated "separated" +//label variable temp_divorced "divorced" +//label variable temp_widowed "widowed" + + +//Cohabiting/married +gen temp_partnered=( idpartner>0) //(include all those who have a partner in hh) +label variable temp_partnered "partnered (married & partner in hh)" + + +//Separated / Divorced / Widowed to Previously partnered +gen temp_pre_partnered=((dms==2|dms==3|dms==4|dms==5) & idpartner==0) //define dummy of previously partnered (this is not useful when the target is singles) +label variable temp_pre_partnered "previously partnered" + +tab2 temp_single temp_partnered +tab2 temp_single temp_pre_partnered +tab2 temp_partnered temp_pre_partnered + +*-------------------------------------------------------------------------------------------------------------------------- +* Regions +* +*-------------------------------------------------------------------------------------------------------------------------- +/* +drgn1 = 2 if db040 == ""PL2"" +drgn1 = 4 if db040 == ""PL4"" +drgn1 = 5 if db040 == ""PL5"" +drgn1 = 6 if db040 == ""PL6"" +drgn1 = 7 if db040 == ""PL7"" +drgn1 = 8 if db040 == ""PL8"" +drgn1 = 9 if db040 == ""PL9"" + +fre drgn1 + + Freq. Percent Valid Cum. + +Valid 2 7479 14.79 14.79 14.79 + 4 8661 17.12 17.12 31.91 + 5 5131 10.14 10.14 42.05 + 6 8766 17.33 17.33 59.38 + 7 5285 10.45 10.45 69.83 + 8 9424 18.63 18.63 88.46 + 9 5835 11.54 11.54 100.00 + Total 50581 100.00 100.00 +*/ + + +cap label define temp_lab_region /// +2 "South Poland" /// +4 "North Poland" /// +5 "West Poland" /// +6 "Lodz Voivodeship" /// +7 "Mazovia (except Warsaw)" /// +8 "Warsaw Capital Region" /// +9 "Swietokrzyskie Voivodeship" + +label values drgn1 temp_lab_region +tab drgn1, gen(temp_region) + +label variable temp_region1 "South Poland (Makroregion Południowy)" +label variable temp_region2 "North Poland (Makroregion Północny)" +label variable temp_region3 "West Poland (Makroregion Południowo-Zachodni)" +label variable temp_region4 "Łódź Voivodeship" +label variable temp_region5 "Mazovia (except Warsaw)" +label variable temp_region6 "Warsaw Capital Region" +label variable temp_region7 "Świętokrzyskie Voivodeship" + +//fre drgn1 +/* +ISSUE: The number of NUTS1 regions changes in Poland. + 2005 - 2014: 6 NUTS1 regions + (5 - Polnocno-Zachodni, 6 - Polnocny, 1- Centralny, 3 - Wschodni, + 2 - Poludniowy, 4 - Poludniowo-Zachodni) + + 2015 - 2018: 9 NUTS 1 regions (unofficial) + + 2018 - 2020: 7 NUTS1 regions + (4 - Polnocno-Zachodni, 6 - Polnocny, 7 - Centralny, 8 - Wschodni, + 2 - Poludniowy, 5 - Poludniowo-Zachodni, + 9 - Wojewodztwo Mazowieckie - parts of centralny and wschodni became + Wojewodztwo Mazowieckie) + +https://stat.gov.pl/en/regional-statistics/classification-of-territorial-... +units/classification-of-territorial-units-for-statistics-nuts/... +the-nuts-classification-in-poland/ + +To address this, we agreed to merge the 3 regions that changed form in 2018 into +one constant aggregate region to permit the inclusion of the remaining +hetereogenity in the data. +*/ +gen temp_drgn1 = drgn1 +replace temp_drgn1 = 10 if inlist(temp_drgn1, 1, 3, 7, 8, 9) + +lab var temp_drgn1 "Region" +lab define temp_drgn1 /// + 2 "Poludniowy (South)" /// + 4 "Polnocno-Zachodni (North-West)" /// + 5 "Poludniowo-Zachodni (South-West)" /// + 6 "Polnocy (North)" /// + 10 "Central + East (Central/East)", replace + +lab values temp_drgn1 temp_drgn1 + +fre temp_drgn1 + +*dummies +tab temp_drgn1, gen(temp_drgn1_) +lab var temp_drgn1_1 "South" +lab var temp_drgn1_2 "North-West" +lab var temp_drgn1_3 "South-West" +lab var temp_drgn1_4 "North" +lab var temp_drgn1_5 "Central + East" + + +*-------------------------------------------------------------------------------------------------------------------------- +* Health status +* +*------------------------------------------------------------------------------------------------------------------------- +merge 1:1 idhh idperson using "temp_dhe.dta" +lab var dhe "Health status - imputed" +fre dhe +drop _merge + +*impute missing values +gen dagsq = dag^2 +fre dag if missing(dhe) + +*ordered probit model +recode dgn dag dagsq drgn1 (-9=.) , gen (dgn2 dag2 dagsq2 drgn12) +fre dgn2 dag2 dagsq2 drgn12 +xi: oprobit dhe i.dgn2 dag2 dagsq ib3.drgn12 if dhe < ., vce(robust) +predict pred_probs1 pred_probs2 pred_probs3 pred_probs4 pred_probs5, pr + +*Identify the category with the highest predicted probability +egen max_prob = rowmax(pred_probs1 pred_probs2 pred_probs3 pred_probs4 pred_probs5) +*Impute missing values of dhe based on predicted probabilities +gen imp_dhe = . +replace imp_dhe = 1 if max_prob == pred_probs1 +replace imp_dhe = 2 if max_prob == pred_probs2 +replace imp_dhe = 3 if max_prob == pred_probs3 +replace imp_dhe = 4 if max_prob == pred_probs4 +replace imp_dhe = 5 if max_prob == pred_probs5 + +sum imp_dhe if missing(dhe) & dag>0 & dag<16 +sum imp_dhe if !missing(dhe) & dag>0 & dag<16 +sum imp_dhe if missing(dhe) & dag>=16 +sum imp_dhe if !missing(dhe) & dag>=16 + +gen dhe_flag = missing(dhe) +lab var dhe_flag "=1 if dhe is imputed" +replace dhe = round(imp_dhe) if missing(dhe) + +bys dhe_flag: fre dhe if dag<=16 +bys dhe_flag: fre dhe if dag>16 + +drop dgn2 dag2 dagsq2 drgn12 _Idgn2_1 pred_probs* max_prob imp_dhe + +/***************************** ADULT CHILD FLAG *******************************/ +/* +Decision 24/10/25: Agreed that to be an adult child the following conditions +have to hold: + - 18+ years old + - Not in a partnership + - Lives with at least one parent + - Is at least 15 years younger than both of their parents + - At least one parent in the hh is working age and not retired. +*/ + +/* Retirement status */ +gen retired = (les == 4) +fre retired + +/* Statutory retirement age (PL: women 60, men 65) */ +gen dagpns = 0 +replace dagpns = 1 if dgn == 1 & dag >= 65 +replace dagpns = 1 if dgn == 0 & dag >= 60 +fre dagpns + +/* Merge in mother/father information */ +add_mother_variables "retired dagpns dag" +add_father_variables "retired dagpns dag" + +/* NEW variable name */ +gen temp_adultchildflag = 0 + +/* Adult child basic definition */ +replace temp_adultchildflag = 1 if (idmother > 0 | idfather > 0) /// + & dag >= 17 & idpartner <= 0 + +/* Exclude if both parents retired or at statutory retirement age */ +replace temp_adultchildflag = 0 if mother_dagpns == 1 & father_dagpns == . +replace temp_adultchildflag = 0 if mother_dagpns == . & father_dagpns == 1 +replace temp_adultchildflag = 0 if mother_dagpns == 1 & father_dagpns == 1 + +replace temp_adultchildflag = 0 if mother_retired == 1 & father_retired == . +replace temp_adultchildflag = 0 if mother_retired == . & father_retired == 1 +replace temp_adultchildflag = 0 if mother_retired == 1 & father_retired == 1 + +replace temp_adultchildflag = 0 if mother_retired == 1 & father_dagpns == 1 +replace temp_adultchildflag = 0 if father_retired == 1 & mother_dagpns == 1 + +/* Exclude if both parents < 15 years older than child */ +replace temp_adultchildflag = 0 if father_dag - dag <= 15 & mother_dag == . +replace temp_adultchildflag = 0 if father_dag == . & mother_dag - dag <= 15 +replace temp_adultchildflag = 0 if father_dag - dag <= 15 & mother_dag - dag <= 15 + +//fre temp_adultchildflag + +*-------------------------------------------------------------------------------------------------------------------------- +* work history +* +*-------------------------------------------------------------------------------------------------------------------------- +/* liwwh: LABOUR MARKET : In work : Work history (length of time in months) Number of months spent in employment*/ +replace liwwh =liwwh /12 +label variable liwwh "work history (length of time in years)" + + +*------------------------------------------------------------ +* Hours worked +*------------------------------------------------------------ +label variable lhw "labour market : hours worked per week" +fre lhw +replace lhw = $max_lhw if lhw > $max_lhw //ensure lhw doesn't go above weekly max 168 minus 42=(6*7) hours of sleep. +//(0 real changes made) +fre lhw + +histogram lhw, percent bin(20) +histogram lhw if dgn==1, percent bin(20) +histogram lhw if dgn==0, percent bin(20) + + +*lhw discretisation + +* chosen hrs bracket +*female hrs bracket +gen byte temp_bracket_0 = 0 +replace temp_bracket_0 = 1 if lhw >= $min_hours_1_0 &dgn==0 +replace temp_bracket_0 = 2 if lhw >= $min_hours_2_0 &dgn==0 +replace temp_bracket_0 = 3 if lhw >= $min_hours_3_0 &dgn==0 +//replace temp_bracket_0 = 4 if lhw >= $min_hours_4_0 &dgn==0 + +*male hrs bracket +gen byte temp_bracket_1 = 0 +replace temp_bracket_1 = 1 if lhw >= $min_hours_1_1 &dgn==1 +replace temp_bracket_1 = 2 if lhw >= $min_hours_2_1 &dgn==1 +replace temp_bracket_1 = 3 if lhw >= $min_hours_3_1 &dgn==1 +//replace temp_bracket_1 = 4 if lhw >= $min_hours_4_1 &dgn==1 + +*female discretised hrs +gen temp_lhw_dobs_0=0 +replace temp_lhw_dobs_0=20 if temp_bracket_0 == 1 +replace temp_lhw_dobs_0=40 if temp_bracket_0 == 2 +replace temp_lhw_dobs_0=50 if temp_bracket_0 == 3 +//replace temp_lhw_dobs_0=50 if temp_bracket_0 == 4 + +//male discretised hrs +gen temp_lhw_dobs_1=0 +replace temp_lhw_dobs_1=20 if temp_bracket_1 == 1 +replace temp_lhw_dobs_1=40 if temp_bracket_1 == 2 +replace temp_lhw_dobs_1=50 if temp_bracket_1 == 3 +//replace temp_lhw_dobs_1=50 if temp_bracket_1 == 4 + +fre temp_lhw_dobs_0 if dgn==0 +fre temp_lhw_dobs_1 if dgn==1 + +*part-time hours +gen pt = (lhw> 0 & lhw<.) * (lhw<40) +lab var pt "part-time employed (<40 hours per week)" + +*full-time or more hours +gen ft = (lhw>0 & lhw<.) * (lhw>=40) +lab var ft "full-time employed (>=40 hours per week)" + + +*------------------------------------------------------------ +* ln(hourly wage) +*------------------------------------------------------------ +//v6: define discritized hours of work as median hours in the choice category +//update in v7: define discritized hours of work as a particular no. (close to mid-point) +*Update in v6: discritize lhw before generating hourly wages, in order to reduce the "division bias" +* wages + +/* +fre yempj //employment income, permanent job (employment contract) +fre yemtj //employment income, temporary job (different than employment contract) +fre yseag //self-employment income from agriculture +fre ysebs //self-employment income from business (non-agricultural) + +. fre yemmy ysemy + +yemmy +----------------------------------------------------------- + | Freq. Percent Valid Cum. +--------------+-------------------------------------------- +Valid 0 | 32870 64.98 64.98 64.98 + 1 | 296 0.59 0.59 65.57 + 2 | 255 0.50 0.50 66.07 + 3 | 258 0.51 0.51 66.58 + 4 | 278 0.55 0.55 67.13 + 5 | 232 0.46 0.46 67.59 + 6 | 313 0.62 0.62 68.21 + 7 | 425 0.84 0.84 69.05 + 8 | 438 0.87 0.87 69.92 + 9 | 394 0.78 0.78 70.70 + 10 | 389 0.77 0.77 71.47 + 11 | 393 0.78 0.78 72.24 + 12 | 14040 27.76 27.76 100.00 + Total | 50581 100.00 100.00 +----------------------------------------------------------- + +ysemy +----------------------------------------------------------- + | Freq. Percent Valid Cum. +--------------+-------------------------------------------- +Valid 0 | 46447 91.83 91.83 91.83 + 1 | 793 1.57 1.57 93.39 + 2 | 167 0.33 0.33 93.72 + 3 | 101 0.20 0.20 93.92 + 4 | 87 0.17 0.17 94.10 + 5 | 91 0.18 0.18 94.28 + 6 | 102 0.20 0.20 94.48 + 7 | 52 0.10 0.10 94.58 + 8 | 68 0.13 0.13 94.72 + 9 | 44 0.09 0.09 94.80 + 10 | 67 0.13 0.13 94.93 + 11 | 106 0.21 0.21 95.14 + 12 | 2456 4.86 4.86 100.00 + Total | 50581 100.00 100.00 +----------------------------------------------------------- +*/ + +/*update 2/2/2021: Note: we do not know the divide of lhw between employment income and self-employed income +//gen temp_obs_wage=temp_y/(lhw*4.3) //observed wages +replace temp_y=temp_y*12/yemmy if yem>0 //this adjustment magnifies the original total monthly income if yemmy<12 & yem>0 +gen temp_obs_wage=temp_y/(lhw*4.3) //observed wages +*/ +/* Employment income in PL model +yempj INCOME : Employment: permanent +yemtj INCOME : Employment temporary +yseag INCOME : Self Employment : Agriculture +ysebs INCOME : Self Employment : Business +*/ + +*------------------------------------------------------------ +* Separate employment and self-employment income +*------------------------------------------------------------ +gen temp_yem = yempj + yemtj // monthly employment income +gen temp_yse = yseag + ysebs // monthly self-employment income + +sum temp_yem if temp_yem < 0 +sum temp_yse if temp_yse < 0 + +*------------------------------------------------------------ +* Adjust income to an annual-equivalent based on months worked +*------------------------------------------------------------ +* not that in EUROMOD annual wages are divided by 12 so we need to multiply by 12 to get back to annual wages +* This adjustment magnifies the income if yemmy < 12 +replace temp_yem = temp_yem * 12 / yemmy if temp_yem > 0 + +* Same for self-employment income +replace temp_yse = temp_yse * 12 / ysemy if temp_yse > 0 + +* Combine adjusted income +gen temp_y = temp_yem + temp_yse + +sum temp_y if temp_y < 0 + +* Calculate observed hourly wage +gen temp_obs_wage=temp_y/(lhw*4.3) + +drop temp_yem temp_yse +*------------------------------------------------------------ +* remove outliers of wages (1% and 99% percentiles) +*------------------------------------------------------------ +count if temp_obs_wage==0 &lhw>0 +//drop if temp_y==0 & lhw>0 //drop obs who have lhw>0 but temp_y=0 +//If wage is zero but hours > 0, treat them as non-workers (lhw = 0). Then remove wage (set to missing). +replace lhw=0 if temp_obs_wage==0 //DP: this allows to keep these obs in the sample +replace temp_obs_wage=. if lhw==0 //(1,015 real changes made, 1,015 to missing) + +duplicates report idperson //count how many unique individuals there are +// still 50581 obs +su temp_obs_wage if lhw>0 +su temp_obs_wage if lhw==0 + +***Trim wages instead of chopping???? +/* +gen keepwage=(inrange(temp_obs_wage, r(p1), r(p99))) //dummy of temp_obs_wage within 1st-99th percentiles +keep if keepwage==1 |lhw==0 //keep workers with wage within 1st-99th percentiles and non-workers +drop keepwage +*/ +centile temp_obs_wage if lhw>0, centile(1 2 3 4 5 95 96 97 98 99) +return list +replace temp_obs_wage = `r(c_1)' if temp_obs_wage <= `r(c_1)' & lhw>0 +replace temp_obs_wage = `r(c_10)' if temp_obs_wage >= `r(c_10)' & temp_obs_wage != . & lhw>0 + +duplicates report idperson //count how many unique individuals +//still 50581 obs +su temp_obs_wage if lhw>0 +/* Variable Obs Mean Std. Dev. Min Max + +temp_obs_w~e 20,864 22.55925 15.3138 .7588967 94.7368 +*/ +/*the mean looks about right. In 2019, the average gross monthly wage in Poland was approximately 4,918.17 PLN. Given that full-time employees typically work around 160 hours per month, +this translates to an average gross hourly wage of about 30.74 PLN. The minimum gross monthly wage in 2019 was 2,250 PLN, equating to a minimum gross hourly rate of 14.70 PLN */ + +//Now restore temp_y using trimmed version of hourly wage +replace temp_y = temp_obs_wage * lhw * 4.3 +sum temp_y if temp_y>0 +/* +Variable Obs Mean Std. Dev. Min Max + +temp_y 20,864 3930.793 2720.384 16.99983 30552.62 +*/ + +//female ln(wage) +gen temp_lnwage=log(temp_y/(temp_lhw_dobs_0*4.3)) if temp_y>0 &dgn==0 //logarithm of hourly wage (yem: monthly employment income; temp_lhw_dobs: discritized Hours worked per week) 4.3=365/(7*12) +//male ln(wage) +replace temp_lnwage=log(temp_y/(temp_lhw_dobs_1*4.3)) if temp_y>0 &dgn==1 //logarithm of hourly wage (yem: monthly employment income; temp_lhw_dobs: discritized Hours worked per week) 4.3=365/(7*12) +label variable temp_lnwage "log(hourly wage)" +sum temp_obs_wage +sum temp_lnwage + +//CHECK +assert lhw>0 if temp_y<. +su lhw if lhw<=0 &temp_y>0 //no obs +//drop if lhw<=0 &temp_y>0 //to eliminate the above outliers +duplicates report idperson //count how many unique individuals there are +//50581 obs + +*------------------------------------------------------------ +* participation (binary: work and not work) +*------------------------------------------------------------ + +gen temp_work=1 if temp_y<. //worker, either employed or self-employed +replace temp_work=0 if temp_y==. //non-worder +fre temp_work +*------------------------------------------------------------ +* age squared +*------------------------------------------------------------ +label variable dag "age" + +gen temp_age2=dag^2 +label variable temp_age2 "age^2" +*------------------------------------------------------------ +* household size +*------------------------------------------------------------ +gen sizecount=1 +bysort idhh:egen temp_hhsize=total(sizecount) +label variable temp_hhsize "household size" +drop sizecount + + +*======================================================================= +* Target samples classification +* +*======================================================================= +*keep working age people only (aged 16-75) +gen temp_workage=(dag>=16 & dag <=75) //dummy of working age (aged 16 to 75) +count if temp_workage==1 + +//@@@ DATA FILTER -"singles" @@@ +add_partner_variables "les temp_workage dag" +sum partner_* + +gen temp_p_student=(partner_les==6) //dummy of having a student partner +label variable temp_p_student "1(with a student partner)" + +gen temp_p_sick_dis=(partner_les==8) //dummy of having a sick or disabled partner +label variable temp_p_sick_dis "1(with a sick or disabled partner)" + +gen temp_p_pensioner=(partner_les==4) //dummy of having partner being a pensioner (updated 3 July 2020) +label variable temp_p_sick_dis "1(with a pensioner partner)" + +gen temp_p_workage=(partner_temp_workage==1) //dummy of having a partner with working age (aged 16-75) + +gen temp_p_elderly=(partner_dag>=70) //dummy of having a partner aged 70 or above +label variable temp_p_elderly "1(with partner aged 70+)" + +drop partner_les partner_temp_workage partner_dag + +*-------------------------------------------------------------------------------------------------------------------------- +* Inclusion in the "singles" sample: single member in the household, working age, not student (les!=6), not sick or disabled (les!=8), not pensioner (les!=4) +* Note: temp_singles includes two mutually exclulsive groups: temp_singles_indep and temp_singles_dep +*-------------------------------------------------------------------------------------------------------------------------- +//(updated 3 July 2020):les!=4 (not pensioner) +//update 16/2/2021 (idpartner>0&(temp_p_student==1|temp_p_sick_dis==1|temp_p_workage==0|temp_p_pensioner==1)) +gen byte temp_singles = ((idpartner==0|(idpartner>0&(temp_p_student==1|temp_p_sick_dis==1|temp_p_workage==0|temp_p_pensioner==1))) & temp_workage == 1 & les != 6 & les != 8 & les != 4) //dummy of target sample +//gen byte temp_singles = ((idpartner==0|temp_p_student==1|temp_p_sick_dis==1|temp_p_workage==0|temp_p_pensioner==1) & temp_workage == 1 & les != 6 & les != 8 & les != 4) //dummy of target sample + +label variable temp_singles "flag: Heckman sample (singles, working age, not student, not sick or disabled, not pensioner )" + +tab les temp_singles +qui count if temp_singles==1 +noi di in y "Target sample singles: number of observations, i.e singles at working age, not student (les!=6), not sick or disabled (les!=8), not pensioner (les!=4): " r(N) //Notice they can be of any marital status +// 10277 obs +*Note that here the definition of "singles" is either those with no partners (not the same as marital status), or with a student partner or sick or disabled partner or out-of-working-age partner +tab les if temp_singles==1 + +*-------------------------------------------------------------------------------------------------------------------------- +* Inclusion in the "singles_indep" sample: single member in the household, working age, not student (les!=6), not sick or disabled (les!=8), not pensioner (les!=4) +* +*-------------------------------------------------------------------------------------------------------------------------- +gen temp_singles_indep=(idpartner==0 & temp_workage == 1 & les != 6 & les != 8 & les != 4) +label variable temp_singles "flag: Heckman sample (singles, working age, not student, not sick or disabled, not pensioner )" +duplicates report idperson //count how many unique individuals there are +//50581 obs + +*-------------------------------------------------------------------------------------------------------------------------- +* Inclusion in the "singles_dep" sample: within work age, not student (les!=6), not sick or disabled (les!=8), not pensioner (les!=4), +* with a partner who is student, sick or disabled, or out of working age +* +*-------------------------------------------------------------------------------------------------------------------------- +//gen temp_singles_dep=(idpartner>0&(temp_p_student==1|temp_p_sick_dis==1|temp_p_workage==0) & temp_workage == 1 & les != 6 & les != 8 & les != 4) +gen temp_singles_dep=(idpartner>0&(temp_p_student==1|temp_p_sick_dis==1|temp_p_workage==0|temp_p_pensioner==1) & temp_workage == 1 & les != 6 & les != 8 & les != 4) //update 16/2/2021 +label variable temp_singles "flag: Heckman sample (with non-flexible partner, working age, not student, not sick or disabled, not pensioner )" +tab les if temp_singles_dep==1 +//double check temp_singles includes two mutually exclulsive groups: temp_singles_indep and temp_singles_dep +assert temp_singles==temp_singles_indep+temp_singles_dep + + +//@@@ DATA FILTER -"couples" @@@ +*-------------------------------------------------------------------------------------------------------------------------- +* Inclusion in the sample: individuals in couples with both partners at working age, not student (les!=6), not sick or disabled (les!=8) +* (Both partners are flexible in labour supply) +*-------------------------------------------------------------------------------------------------------------------------- +//(updated 3 July 2020):les!=4 (not pensioner) +gen byte temp_couples = (idpartner>0 & temp_p_student==0 & temp_p_sick_dis==0 & temp_p_workage==1 &temp_p_pensioner==0 & temp_workage == 1 & les != 6 & les != 8& les != 4) //dummy of target sample for "couples" +label variable temp_couples "flag: Heckman sample (couples, working age, not student, sick or disabled, not pensioner)" +tab les temp_couples +qui count if temp_couples==1 +noi di in y "Target sample couples: number of observations, i.e couples at working age, not student (les!=6), not sick or disabled (les!=8), not pensioner (les!=4): " r(N) //Notice they can be of any marital status +tab les if temp_couples==1 +tab dms if temp_couples==1 + + +//@@@ DATA FILTER -"not_flexible" @@@ +gen temp_not_flexible=(temp_singles==0 &temp_couples==0) + +tab lhw if temp_not_flexible==1 +assert temp_singles+temp_couples+temp_not_flexible==1 //check the 3 categories are exclusive +su temp_singles_indep temp_singles_dep temp_couples temp_not_flexible +duplicates report idperson //count how many unique individuals there are +// 50581 obs + +//check hours of work +fre temp_lhw_dobs_0 if dgn==0 & temp_couples ==1 //24.3% with zero hours +fre temp_lhw_dobs_1 if dgn==1 & temp_couples ==1 //8.6% with zero hours + +fre temp_lhw_dobs_0 if dgn==0 & temp_singles_indep==1 //33.9% with zero hours +fre temp_lhw_dobs_1 if dgn==1 & temp_singles_indep==1 //24.3% with zero hours + +fre temp_lhw_dobs_0 if dgn==0 & temp_singles_dep==1 //48.2% with zero hours +fre temp_lhw_dobs_1 if dgn==1 & temp_singles_dep==1 //26.5% with zero hours +/*In 2019, Poland's economic inactivity rates among individuals aged 15 to 64 were as follows: +Women: 37% +Men: 26% +This is higher than EU average but the data looks about right*/ + +save beforeheckman,replace + +*------------------------------------------------------------ +* Heckman wage equations for male and female, respectively +*------------------------------------------------------------ +use beforeheckman,clear +//drop if temp_obs_wage<14 & lhw>0 + +duplicates report idperson //count how many unique individuals there are + +* dgn: female 0, male 1 +*Assumption: people don't distinguish being employed and self-employed when making both participation choices and hours of work choices + label variable temp_d_ch "1(children aged 0-17)" + label variable temp_d_ch2 "1(children aged 0-2)" + label variable temp_d_ch6 "1(children aged 3-6)" + label variable temp_d_ch12 "1(children aged 7-12)" + label variable temp_d_ch17 "1(children aged 13-17)" + + + label variable temp_n_ch "number of children aged 0-17" + label variable temp_n_ch2 "number of children aged 0-2" + label variable temp_n_ch6 "number of children aged 3-6" + label variable temp_n_ch12 "number of children aged 7-12" + label variable temp_n_ch17 "number of children aged 13-17" + +//add interactions of education with age +gen temp_int_dehH_dag = temp_d_deh_H*dag +gen temp_int_dehM_dag = temp_d_deh_M*dag +gen temp_int_dehL_dag = temp_d_deh_L*dag +lab var temp_int_dehH_dag "high education*age" +lab var temp_int_dehM_dag "medium education*age" +lab var temp_int_dehL_dag "low education*age" + +//Add occupational class dummies =A collapsed versin of ISCO = skill level +/*LABOUR MARKET : Occupation (ISCO 1-Digit) + 0 Armed forces + 1 Senior officials and managers + 2 Professionals + 3 Technicians and associate professionals + 4 Clerks + 5 Service and sales workers + 6 Skilled agricultural + 7 Craft and trades workers + 8 Plant and machine operators + 9 Elementary occupations + -1 Not Applicable*/ +recode loc (1/2 = 4) (3=3) (4/8=2) (9=1) (0=0) (10=0) (-1=0), gen(loc2) +lab var loc2 "Occupation (skill level) - 4 categories + never worked" +cap label define loc2 4 "level 4" 3 "level 3" 2 "level 2" 1 "level 1" 0 "never worked" +label values loc2 loc2 +fre loc2 +gen temp_loc2_0 =(loc2==0) +gen temp_loc2_1 =(loc2==1) +gen temp_loc2_2 =(loc2==2) +gen temp_loc2_3 =(loc2==3) +gen temp_loc2_4 =(loc2==4) +replace temp_lnwage=. if loc2==0 +lab var temp_loc2_1 "skill level 1 (ISCO 9)" +lab var temp_loc2_2 "skill level 2 (ISCO 4-8)" +lab var temp_loc2_3 "skill level 3 (ISCO 3)" +lab var temp_loc2_4 "skill level 4 (ISCO 1-2)" + +bysort deh: sum temp_obs_wage +bysort loc2: sum temp_obs_wage + +*health status dummies +tab dhe, gen (temp_dhe_) + + +//////////////////////////////////////////// +/*Run wage regression for the whole sample*/ +//////////////////////////////////////////// + +foreach gender in 0 1{ //beginning of gender loop +//local gender=0 //for debugging +capture drop temp_lnw_`gender' +capture drop temp_heckman_`gender' +capture drop temp_u_`gender' +capture drop temp_wage_`gender' +*note: region 6 is Warsaw +***************************************************************************************************************************************************** + local covariates "dag temp_age2 temp_loc2_2 temp_loc2_3 temp_loc2_4 liwwh temp_dhe_2 temp_dhe_3 temp_dhe_4 temp_dhe_5 temp_region1 temp_region2 temp_region3 temp_region4 temp_region5 temp_region6" + local selection "temp_single temp_pre_partnered temp_n_ch temp_d_ch2 dag temp_age2 temp_loc2_2 temp_loc2_3 temp_loc2_4 liwwh temp_dhe_2 temp_dhe_3 temp_dhe_4 temp_dhe_5 temp_region1 temp_region2 temp_region3 temp_region4 temp_region5 temp_region6" + //DP: part-time dummy had a positive effect on wages + +heckman temp_lnwage `covariates' if dgn==`gender' & temp_not_flexible==0, /// +select(`selection') twostep +******************************************************************************************************************************************************* + +**************** +*output tables * +**************** +version 13 + +matrix results = r(table) +matrix results = results[1..6,1...]' //extract the first six rows of results, and then transpose results +if (`gender' == 0){ +putexcel set "$results_wi/all/wage", sheet("female wage") replace +} +else{ +putexcel set "$results_wi/all/wage", sheet("male wage") modify +} +*putexcel set gender`gender'_wages, replace +putexcel A3 = matrix(results, names) //names nformat(number_d2) //write estimates in Excel from cell A3 (Stata 13) +//putexcel A3 = matrix(results), names nformat(number_d2) //write in Excel from cell A3 (Stata 15) +putexcel A45=("sigma") +putexcel B45=(e(sigma)) + +putexcel A46=("rho") +putexcel B46=(e(rho)) + +//predicted log wage +predict temp_lnw_`gender', ycon //predict logwage (ycon option: expected value of the dependent variable conditional on the dependent variable being observed) +gen temp_heckman_`gender'=( e(sample)==1) + +sum temp_lnwage temp_lnw_`gender' if e(sample) & temp_lnwage != . // RMK: average predicted on observed only +sum temp_lnwage temp_lnw_`gender' if e(sample) // RMK: average predicted on all + +sum temp_lnwage temp_lnw_`gender' if e(sample) & temp_lnwage != . // RMK: average predicted on observed only +sum temp_lnwage temp_lnw_`gender' if e(sample) // RMK: average predicted on all + +//R^2 +predict temp_lnw2_`gender' if e(sample), ycon +corr temp_lnwage temp_lnw2_`gender' if e(sample) +putexcel A48=("R^2") +putexcel B48=(r(rho)^2) //R^2 of wage eqn +gen temp_R2_lnwage_`gender'=r(rho)^2 //store this variable for writing to tex later + +//RMSE of wage eqn +gen double temp_u_`gender' = temp_lnwage - temp_lnw_`gender' if e(sample) +sum temp_u_`gender' + +putexcel A47=("RMSE of wage eqn") +putexcel B47=(r(sd)) //sd of the residuals of wage eqn + +global heckmanwage "`covariates'" +global heckmanselection "`covariates' temp_single temp_pre_partnered temp_n_ch temp_d_ch2" + +macro list heckmanwage +//display labels for covariates of wage eqn & label for the dependent variable temp_lnwage (log(hourly wage)) +global n_wagevars: word count $heckmanwage //count the number of vars in list $heckmanwage + +local row = 4 +foreach x of varlist $heckmanwage{ +describe `x' +local varlabel : var label `x' +putexcel B`row' = ("`varlabel'") +describe temp_lnwage +local ylabel: var label temp_lnwage +putexcel A`row' = ("`ylabel'") +local row = `row'+1 +} +//for _cons +describe temp_lnwage +local ylabel: var label temp_lnwage +local n_wagevars=4+$n_wagevars +putexcel A`n_wagevars'= ("`ylabel'") + + +//display labels for covariates of selection eqn +macro list heckmanselection +local row = 4+$n_wagevars+1 //"+1" because need to leave a cell for _cons for the wage eqn +foreach x of varlist $heckmanselection { +describe `x' +local varlabel : var label `x' +putexcel B`row' = ("`varlabel'") + +local row = `row'+1 +} + +//put in variance-covariance matrix of heckman +matrix results=e(V) +if (`gender' == 0){ +putexcel set "$results_wi/all/wage_eV", sheet("female wage e(V)") replace +} +else{ +putexcel set "$results_wi/all/wage_eV", sheet("male wage e(V)") modify +} +putexcel A3 = matrix(results, names) //names nformat(number_d2) //write e(V) in Excel from cell A3 (Stata 13) + +//display labels for e(V) matrix +//Labels on the Excel rows (for e(V)) +//-labels of covariates for wage eqn +local row = 5 +foreach x of varlist $heckmanwage { +describe `x' +local varlabel : var label `x' +putexcel B`row' = ("`varlabel'") +local ylabel: var label temp_lnwage +putexcel A`row' = ("`ylabel'") +local row = `row'+1 +} +//-(put the label of "temp_lnwage" for _cons in wage eqn) +local ylabel: var label temp_lnwage +local row=5+$n_wagevars +putexcel A`row'= ("`ylabel'") + +//-labels of covariates for selection eqn +local row = 5+$n_wagevars+1 //"+1" because need to leave a cell for _cons for the wage eqn +foreach x of varlist $heckmanselection { +describe `x' +local varlabel : var label `x' +putexcel B`row' = ("`varlabel'") +local row = `row'+1 +} + +//Labels on the Excel columns (for e(V)) +//-labels of covariates for wage eqn + +local col=3 +foreach x of varlist $heckmanwage { +describe `x' +local varlabel : var label `x' +excelcol `col' //Convert a column index into a name of an Excel column (e.g. 3->C) +local colname `r(column)' //`colname'is now the name of Excel column +putexcel B`row' = ("`varlabel'") +local ylabel: var label temp_lnwage +putexcel `colname'3 = ("`ylabel'") +putexcel `colname'4 = ("`varlabel'") +local col = `col'+1 +} +//-(put the label of "temp_lnwage" for _cons in wage eqn) +local ylabel: var label temp_lnwage +local col=3+$n_wagevars +excelcol `col' //Convert a column index into a name of an Excel column (e.g. 3->C) +local colname `r(column)' //`colname'is now the name of Excel column +putexcel `colname'3= ("`ylabel'") +//-labels of covariates for selection eqn + +local col=3+$n_wagevars+1 //"+1" because need to leave a cell for _cons for the wage eqn +foreach x of varlist $heckmanselection { +describe `x' +local varlabel : var label `x' +excelcol `col' //Convert a column index into a name of an Excel column (e.g. 3->C) +local colname `r(column)' //`colname'is now the name of Excel column +putexcel `colname'4 = ("`varlabel'") +local col = `col'+1 +} +//for e(v) matrix row, put "_cons" as the last covariate for selection eqn (strangely, without this, the last covariate label will be the last covariate of the wage eqn, in this case "Northern Ireland". this does not happen in column labels) +//Also strangely, the following commands do not work if I put them before displaying labels for e(V) columns +if (`gender' == 0){ +putexcel set "$results_wi/all/wage_eV", sheet("female wage e(V)") modify +} +else{ +putexcel set "$results_wi/all/wage_eV", sheet("male wage e(V)") modify +} +global n_selectionvars: word count $heckmanselection //count the number of vars in list $heckmanselection +local n_selectionvars=5+$n_wagevars+1+$n_selectionvars +putexcel B`n_selectionvars'= ("_cons") +estimates save heckman_`gender',replace //to save .ster files +eststo heckman_`gender' +estadd scalar R2=temp_R2_lnwage_`gender' +//esttab heckman_`gender' using s_heckman_`gender'.csv, replace label cells(b(fmt(20)) t(par fmt(2))) plain //for simulation (plain, including all digits) +esttab heckman_`gender' using heckman_`gender'.csv, replace label cells(b(star fmt(3)) t(par fmt(2))) stats(R2 N) //for writing csv (including at least three non-zero digits) +if (`gender' == 0){ +esttab heckman_`gender' using heckman_women.tex, replace label cells(b(star fmt(3)) t(par fmt(2))) stats(R2 N) /// +title(Determinants of hourly wages, women aged 16-75. Source: Our elaboration on EUROMOD 2019 input data for Poland (EU-SILC)\label{tab:wage-F}) //for writing tex(including at least three non-zero digits) +} +else{ +esttab heckman_`gender' using heckman_men.tex, replace label cells(b(star fmt(3)) t(par fmt(2))) stats(R2 N) /// +title(Determinants of hourly wages, men aged 16-75. Source: Our elaboration on EUROMOD 2019 input data for Poland (EU-SILC)\label{tab:wage-M}) //for writing tex(including at least three non-zero digits) +} + +//capture drop R2 +*anti-log transformation +// gen double temp_u_`gender' = temp_lnwage - temp_lnw_`gender' if e(sample) //this line was moved forward when entering Excel of RMSE +sum temp_u_`gender' + +gen temp_wage_`gender' = exp(temp_lnw_`gender' + rnormal(0,r(sd))) // to avoid retransformation bias + + +} //end of gender loop + + +esttab heckman_1 heckman_0 using "$results_wi/all/heckman_10.tex", replace label cells(b(star fmt(3))) stats(R2 N) nonumbers mtitles("Men" "Women") /// +collabels(none) /// +title(Determinants of hourly wages, men and women aged 16-75. Source: Our elaboration on EUROMOD 2019 input data for Poland /// +\label{tab:wage-MF}) /// +addnote("*** Results significant at 0.1\%, ** 1\%, * 5\%.") //for writing tex including female and male(including at least three non-zero digits) + +esttab heckman_1 heckman_0 using "$results_wi/all/heckman_10.csv", replace label cells(b(star fmt(3))) stats(R2 N) nonumbers mtitles("Men" "Women") /// +title(Determinants of hourly wages, men and women aged 16-75. Source: Our elaboration on EUROMOD 2019 input data for Poland /// +\label{tab:wage-MF}) /// +collabels(none) /// +addnote("*** Results significant at 0.1\%, ** 1\%, * 5\%.") //for writing csv including female and male(including at least three non-zero digits) + +gen temp_heckman=temp_heckman_0 //dummy of being included in the Heckman sample for female +replace temp_heckman=temp_heckman_1 if dgn==1 //dummy of being included in the Heckman sample for male + +*======================================================================= +* wage imputations +*======================================================================= + +*------------------------------------------------------------ +* // @@@ WAGE IMPUTATION METHOD #wage1 @@@ +* make predicted wage=yivwg for everyone +*------------------------------------------------------------ + +replace yivwg=temp_wage_0 if dgn==0 //For female, make predicted wage=yivwg (yivwg: name for predicted hourly wage in Euromod) +replace yivwg=temp_wage_1 if dgn==1 //For male, make predicted wage=yivwg (yivwg: name for predicted hourly wage in Euromod) + +recode yivwg (.=-1) //not-wages as -1 + +su temp_obs_wage yivwg if temp_work==1 & temp_heckman==1& yivwg!=-1 +bysort dgn:su temp_obs_wage yivwg if temp_work==1 & temp_heckman==1 & yivwg!=-1 + +bysort dgn:su temp_obs_wage yivwg if temp_work==1 & temp_heckman==1 & yivwg!=-1 & temp_obs_wage<14 + + + +********************************************* +* Graph of predicted wage vs. observed wage * +********************************************* +************** +*scatterplot * +************** +foreach gender in 0 1 { //beginning of gender loop + twoway (scatter yivwg temp_obs_wage if dgn==`gender' & temp_heckman_`gender'==1 & yivwg!=.) (line temp_obs_wage temp_obs_wage if dgn==`gender') + graph export "$results_wi/all/wages_scatter_`gender'.png", as(png) replace + +************ +*histogram * +************ +/*DP: In 2019, the average gross monthly wage in Poland was approximately 4,918.17 PLN. Given that full-time employees typically work around 160 hours per month, +this translates to an average gross hourly wage of about 30.74 PLN. The minimum gross monthly wage in 2019 was 2,250 PLN, equating to a minimum gross hourly rate of 14.70 PLN */ + +if (`gender' == 0) { + twoway /// + (histogram temp_obs_wage if dgn==`gender' & temp_heckman_`gender'==1 & temp_obs_wage != . & temp_obs_wage<100, /// + percent color(green) start(0) width(1)) /// + (histogram yivwg if dgn==`gender' & temp_heckman_`gender'==1 & temp_obs_wage != .& yivwg<100, /// + percent fcolor(none) lcolor(black) start(0) width(1)) /// + , legend(order(1 "observed" 2 "predicted")) /// + subtitle("Women") /// + ytitle("percent") /// + xtitle("hourly wage, PLN") /// + xscale(range(0 100)) +} +else { + twoway /// + (histogram temp_obs_wage if dgn==`gender' & temp_heckman_`gender'==1 & temp_obs_wage != .& temp_obs_wage<100, /// + percent color(green) start(0) width(1)) /// + (histogram yivwg if dgn==`gender' & temp_heckman_`gender'==1 & temp_obs_wage != .& yivwg<100, /// + percent fcolor(none) lcolor(black) start(0) width(1)) /// + , legend(order(1 "observed" 2 "predicted")) /// + subtitle("Men") /// + ytitle("percent") /// + xtitle("hourly wage, PLN") /// + xscale(range(0 100)) +} +graph export "$results_wi/all/obs_wage_`gender'.png", as(png) replace + } //end of gender loop + + +duplicates report + +save afterheckman,replace + +////////////////////////////////////////////////////////////////////// +/*Decision: run wage regression separately for low and high earners */ +////////////////////////////////////////////////////////////////////// +/*DP: In 2019, the average gross monthly wage in Poland was approximately 4,918.17 PLN. Given that full-time employees typically work around 160 hours per month, +this translates to an average gross hourly wage of about 30.74 PLN. The minimum gross monthly wage in 2019 was 2,250 PLN, equating to a minimum gross hourly rate of 14.70 PLN +*/ + +histogram temp_obs_wage if deh<3, percent +histogram temp_obs_wage if deh>=3, percent + +histogram temp_obs_wage if loc2==1, percent +histogram temp_obs_wage if loc2==2, percent +histogram temp_obs_wage if loc2==3, percent +histogram temp_obs_wage if loc2==4, percent + +histogram temp_obs_wage , percent +histogram temp_obs_wage if temp_obs_wage<10, percent +histogram temp_obs_wage if temp_obs_wage>=10, percent + +//low wages group +gen group1 = . +replace group1 = 1 if temp_obs_wage>0 & temp_obs_wage<10 +replace group1 = 0 if temp_obs_wage==. +fre group1 + +//high wages group +gen group2 = . +replace group2 = 1 if temp_obs_wage>=10 & temp_obs_wage<. +replace group2 = 0 if temp_obs_wage==. +fre group2 + +gen nonworking = temp_obs_wage==. +fre group1 group2 nonworking + +histogram temp_obs_wage if group1<., percent +histogram temp_obs_wage if group2<., percent + +**************************************************************************************************************** +*** 1) Heckman estimated on the sub-sample of individuals with low wages +**************************************************************************************************************** + +foreach gender in 0 1{ //loop for women and men +*local gender=0 //for debugging +capture drop temp_lnw_`gender'_group1 +capture drop temp_heckman_`gender'_group1 +capture drop temp_u_`gender'_group1 +capture drop temp_wage_`gender'_group1 + +************************************************************************************************************************************************************ + local covariates "dag temp_age2 temp_loc2_2 temp_loc2_3 temp_loc2_4 liwwh temp_dhe_2 temp_dhe_3 temp_dhe_4 temp_dhe_5 temp_region1 temp_region2 temp_region3 temp_region4 temp_region5 temp_region6" //temp_d_deh_M temp_d_deh_H temp_int_dehM_dag temp_int_dehH_dag + local selection "temp_single temp_pre_partnered temp_n_ch temp_d_ch2 dag temp_age2 temp_loc2_2 temp_loc2_3 temp_loc2_4 liwwh temp_dhe_2 temp_dhe_3 temp_dhe_4 temp_dhe_5 temp_region1 temp_region2 temp_region3 temp_region4 temp_region5 temp_region6" //temp_d_deh_M temp_d_deh_H temp_int_dehM_dag temp_int_dehH_dag + + heckman temp_lnwage `covariates' if dgn==`gender' & temp_not_flexible==0 & group1<., /// +select(`selection') twostep +************************************************************************************************************************************************************ + +**************** +*output tables * +**************** +version 13 + +matrix results = r(table) +matrix results = results[1..6,1...]' //extract the first six rows of results, and then transpose results +if (`gender' == 0){ +putexcel set "$results_wi/wage", sheet("female wage_group1") replace +} +else{ +putexcel set "$results_wi/wage", sheet("male wage_group1") modify +} +*putexcel set hu_gender`gender'_wages, replace +putexcel A3 = matrix(results, names) //names nformat(number_d2) //write estimates in Excel from cell A3 (Stata 13) +//putexcel A3 = matrix(results), names nformat(number_d2) //write in Excel from cell A3 (Stata 15) +putexcel A45=("sigma") +putexcel B45=(e(sigma)) + +putexcel A46=("rho") +putexcel B46=(e(rho)) + +////////////////////////////////////////predicted log wage//////////////////////////////////////////////////////////////////////////////////////////////////////////////// +predict temp_lnw_`gender'_group1, ycon //predict logwage (ycon option: expected value of the dependent variable conditional on the dependent variable being observed) +gen temp_heckman_`gender'_group1=( e(sample)==1) + +sum temp_lnwage temp_lnw_`gender'_group1 if e(sample) & temp_lnwage != . // RMK: average predicted on observed only +sum temp_lnwage temp_lnw_`gender'_group1 if e(sample) // RMK: average predicted on all + +gen double temp_u_`gender'_group1 = temp_lnwage - temp_lnw_`gender'_group1 if e(sample) +sum temp_u_`gender'_group1 + +//////////////////////////////////////predicted probability of being employed////////////////////////////////////////////////////////////////////////////////////////////// +* Predict the linear prediction (xbsel) from the selection equation +predict xbsel_`gender'_group1, xbsel +*Convert the linear prediction into a probability of being employed using the normal CDF +gen temp_pr_`gender'_group1 = normal(xbsel_`gender'_group1) +sum temp_pr_`gender'_group1 if e(sample) +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +putexcel A47=("RMSE of wage eqn") +putexcel B47=(r(sd)) //sd of the residuals of wage eqn + +global heckmanwage "`covariates'" +global heckmanselection "`selection'" + +macro list heckmanwage +//display labels for covariates of wage eqn & label for the dependent variable temp_lnwage (log(hourly wage)) +global n_wagevars: word count $heckmanwage //count the number of vars in list $heckmanwage + +local row = 4 +foreach x of varlist $heckmanwage{ +describe `x' +local varlabel : var label `x' +putexcel B`row' = ("`varlabel'") +describe temp_lnwage +local ylabel: var label temp_lnwage +putexcel A`row' = ("`ylabel'") +local row = `row'+1 +} +//for _cons +describe temp_lnwage +local ylabel: var label temp_lnwage +local n_wagevars=4+$n_wagevars +putexcel A`n_wagevars'= ("`ylabel'") + + +//display labels for covariates of selection eqn +macro list heckmanselection +local row = 4+$n_wagevars+1 //"+1" because need to leave a cell for _cons for the wage eqn +foreach x of varlist $heckmanselection { +describe `x' +local varlabel : var label `x' +putexcel B`row' = ("`varlabel'") + +local row = `row'+1 +} + + +//put in variance-covariance matrix of heckman +matrix results=e(V) +if (`gender' == 0){ +putexcel set "$results_wi/wage_eV", sheet("female wage e(V)_group1") replace +} +else{ +putexcel set "$results_wi/wage_eV", sheet("male wage e(V)_group1") modify +} +putexcel A3 = matrix(results, names) //names nformat(number_d2) //write e(V) in Excel from cell A3 (Stata 13) + +//display labels for e(V) matrix +//Labels on the Excel rows (for e(V)) +//-labels of covariates for wage eqn +local row = 5 +foreach x of varlist $heckmanwage { +describe `x' +local varlabel : var label `x' +putexcel B`row' = ("`varlabel'") +local ylabel: var label temp_lnwage +putexcel A`row' = ("`ylabel'") +local row = `row'+1 +} +//-(put the label of "temp_lnwage" for _cons in wage eqn) +local ylabel: var label temp_lnwage +local row=5+$n_wagevars +putexcel A`row'= ("`ylabel'") + +//-labels of covariates for selection eqn +local row = 5+$n_wagevars+1 //"+1" because need to leave a cell for _cons for the wage eqn +foreach x of varlist $heckmanselection { +describe `x' +local varlabel : var label `x' +putexcel B`row' = ("`varlabel'") +local row = `row'+1 +} + +//Labels on the Excel columns (for e(V)) +//-labels of covariates for wage eqn + +local col=3 +foreach x of varlist $heckmanwage { +describe `x' +local varlabel : var label `x' +excelcol `col' //Convert a column index into a name of an Excel column (e.g. 3->C) +local colname `r(column)' //`colname'is now the name of Excel column +putexcel B`row' = ("`varlabel'") +local ylabel: var label temp_lnwage +putexcel `colname'3 = ("`ylabel'") +putexcel `colname'4 = ("`varlabel'") +local col = `col'+1 +} +//-(put the label of "temp_lnwage" for _cons in wage eqn) +local ylabel: var label temp_lnwage +local col=3+$n_wagevars +excelcol `col' //Convert a column index into a name of an Excel column (e.g. 3->C) +local colname `r(column)' //`colname'is now the name of Excel column +putexcel `colname'3= ("`ylabel'") +//-labels of covariates for selection eqn + +local col=3+$n_wagevars+1 //"+1" because need to leave a cell for _cons for the wage eqn +foreach x of varlist $heckmanselection { +describe `x' +local varlabel : var label `x' +excelcol `col' //Convert a column index into a name of an Excel column (e.g. 3->C) +local colname `r(column)' //`colname'is now the name of Excel column +putexcel `colname'4 = ("`varlabel'") +local col = `col'+1 +} +//for e(v) matrix row, put "_cons" as the last covariate for selection eqn (strangely, without this, the last covariate label will be the last covariate of the wage eqn, in this case "Northern Ireland". this does not happen in column labels) +//Also strangely, the following commands do not work if I put them before displaying labels for e(V) columns +if (`gender' == 0){ +putexcel set "$results_wi/wage_eV", sheet("female wage e(V)_group1") modify +} +else{ +putexcel set "$results_wi/wage_eV", sheet("male wage e(V)_group1") modify +} +global n_selectionvars: word count $heckmanselection //count the number of vars in list $heckmanselection +local n_selectionvars=5+$n_wagevars+1+$n_selectionvars +putexcel B`n_selectionvars'= ("_cons") +estimates save "$results_wi/heckman_`gender'_group1",replace //to save .ster files + + +eststo heckman_`gender'_group1 +//esttab heckman_`gender' using s_heckman_`gender'.csv, replace label cells(b(fmt(20)) t(par fmt(2))) plain //for simulation (plain, including all digits) +esttab heckman_`gender'_group1 using "$results_wi/heckman_`gender'_group1.csv", replace label cells(b(star fmt(a3)) t(par fmt(2))) //for writing (including at least three non-zero digits) + +*anti-log transformation +// gen double temp_u_`gender' = temp_lnwage - temp_lnw_`gender' if e(sample) //this line was moved forward when entering Excel of RMSE +sum temp_u_`gender'_group1 + +gen temp_wage_`gender'_group1 = exp(temp_lnw_`gender'_group1 + rnormal(0,r(sd))) // to avoid retransformation bias + +//R^2 +predict temp_lnw2_`gender'_group1 if e(sample), ycon +corr temp_lnwage temp_lnw2_`gender'_group1 if e(sample) +putexcel A48=("R^2") +putexcel B48=(r(rho)^2) //R^2 of wage eqn +gen temp_R2_lnwage_`gender'_group1=r(rho)^2 //store this variable for writing to tex later + +estadd scalar R2=temp_R2_lnwage_`gender'_group1 + +} //end of a loop for gender + + +//esttab heckman_0 heckman_1 using heckman_01.csv, replace label cells(b(star fmt(a3)) t(par fmt(2))) //for writing (including at least three non-zero digits) +esttab heckman_1_group1 heckman_0_group1 using "$results_wi/heckman_10_group1.tex", replace label cells(b(star fmt(3))) stats(R2 N) nonumbers mtitles("Men" "Women") /// +collabels(none) /// +title(Determinants of hourly wages, men and women aged 16-75 (group 1: low wages). Source: Our elaboration on PL EU-SILC input data for 2019 /// +\label{tab:wage-MF}) /// +addnote("*** Results significant at 0.1\%, ** 1\%, * 5\%.") //for writing tex including female and male(including at least three non-zero digits) + +esttab heckman_1_group1 heckman_0_group1 using "$results_wi/heckman_10_group1.csv", replace label cells(b(star fmt(3))) stats(R2 N) nonumbers mtitles("Men" "Women") /// +title(Determinants of hourly wages, men and women aged 16-75 (group 1: low wages). Source: Our elaboration on PL EU-SILC input data for 2019 /// +\label{tab:wage-MF}) /// +collabels(none) /// +addnote("*** Results significant at 0.1\%, ** 1\%, * 5\%.") //for writing csv including female and male(including at least three non-zero digits) + + +//dummy of being included in the Heckman sample +gen temp_heckman_group1=temp_heckman_0_group1 if dgn==0 & group1<. +replace temp_heckman_group1=temp_heckman_1_group1 if dgn==1 & group1<. + + + + +*********************************************************************************************************** +*** 2) Heckman estimated on the sub-sample of individuals with high wages +*** Wage equation controls for lagged wage +*********************************************************************************************************** +foreach gender in 0 1{ //loop for women and men +*local gender=0 //for debugging +capture drop temp_lnw_`gender'_group2 +capture drop temp_heckman_`gender'_group2 +capture drop temp_u_`gender'_group2 +capture drop temp_wage_`gender'_group2 + + +************************************************************************************************************************************************************ + local covariates "dag temp_age2 temp_loc2_2 temp_loc2_3 temp_loc2_4 liwwh temp_dhe_2 temp_dhe_3 temp_dhe_4 temp_dhe_5 temp_region1 temp_region2 temp_region3 temp_region4 temp_region5 temp_region6" //temp_d_deh_M temp_d_deh_H temp_int_dehM_dag temp_int_dehH_dag + local selection "temp_single temp_pre_partnered temp_n_ch temp_d_ch2 dag temp_age2 temp_loc2_2 temp_loc2_3 temp_loc2_4 liwwh temp_dhe_2 temp_dhe_3 temp_dhe_4 temp_dhe_5 temp_region1 temp_region2 temp_region3 temp_region4 temp_region5 temp_region6" //temp_d_deh_M temp_d_deh_H temp_int_dehM_dag temp_int_dehH_dag + + local filter "dgn==`gender' & temp_not_flexible==0 & group2<." + heckman temp_lnwage `covariates' if `filter', select(`selection') twostep +************************************************************************************************************************************************************ + +**************** +*output tables * +**************** +version 13 + +matrix results = r(table) +matrix results = results[1..6,1...]' //extract the first six rows of results, and then transpose results +if (`gender' == 0){ +putexcel set "$results_wi/wage", sheet("female wage_group2") modify +} +else{ +putexcel set "$results_wi/wage", sheet("male wage_group2") modify +} +*putexcel set hu_gender`gender'_wages, replace +putexcel A3 = matrix(results, names) //names nformat(number_d2) //write estimates in Excel from cell A3 (Stata 13) +//putexcel A3 = matrix(results), names nformat(number_d2) //write in Excel from cell A3 (Stata 15) +putexcel A45=("sigma") +putexcel B45=(e(sigma)) + +putexcel A46=("rho") +putexcel B46=(e(rho)) + +//////////////////////////////////////predicted log wage////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +predict temp_lnw_`gender'_group2, ycon //predict logwage (ycon option: expected value of the dependent variable conditional on the dependent variable being observed) +gen temp_heckman_`gender'_group2=( e(sample)==1) + +sum temp_lnwage temp_lnw_`gender'_group2 if e(sample) & temp_lnwage != . // RMK: average predicted on observed only +sum temp_lnwage temp_lnw_`gender'_group2 if e(sample) // RMK: average predicted on all + +gen double temp_u_`gender'_group2 = temp_lnwage - temp_lnw_`gender'_group2 if e(sample) +sum temp_u_`gender'_group2 + +//////////////////////////////////////predicted probability of being employed////////////////////////////////////////////////////////////////////////////////////////////// +* Predict the linear prediction (xbsel) from the selection equation +predict xbsel_`gender'_group2, xbsel +*Convert the linear prediction into a probability of being employed using the normal CDF +gen temp_pr_`gender'_group2 = normal(xbsel_`gender'_group2) +sum temp_pr_`gender'_group2 if e(sample) +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +putexcel A47=("RMSE of wage eqn") +putexcel B47=(r(sd)) //sd of the residuals of wage eqn + +global heckmanwage "`covariates'" +global heckmanselection "`selection'" + +macro list heckmanwage +//display labels for covariates of wage eqn & label for the dependent variable temp_lnwage (log(hourly wage)) +global n_wagevars: word count $heckmanwage //count the number of vars in list $heckmanwage + +local row = 4 +foreach x of varlist $heckmanwage{ +describe `x' +local varlabel : var label `x' +putexcel B`row' = ("`varlabel'") +describe temp_lnwage +local ylabel: var label temp_lnwage +putexcel A`row' = ("`ylabel'") +local row = `row'+1 +} +//for _cons +describe temp_lnwage +local ylabel: var label temp_lnwage +local n_wagevars=4+$n_wagevars +putexcel A`n_wagevars'= ("`ylabel'") + + +//display labels for covariates of selection eqn +macro list heckmanselection +local row = 4+$n_wagevars+1 //"+1" because need to leave a cell for _cons for the wage eqn +foreach x of varlist $heckmanselection { +describe `x' +local varlabel : var label `x' +putexcel B`row' = ("`varlabel'") + +local row = `row'+1 +} + + +//put in variance-covariance matrix of heckman +matrix results=e(V) +if (`gender' == 0){ +putexcel set "$results_wi/wage_eV", sheet("female wage e(V)_group2") modify +} +else{ +putexcel set "$results_wi/wage_eV", sheet("male wage e(V)_group2") modify +} +putexcel A3 = matrix(results, names) //names nformat(number_d2) //write e(V) in Excel from cell A3 (Stata 13) + +//display labels for e(V) matrix +//Labels on the Excel rows (for e(V)) +//-labels of covariates for wage eqn +local row = 5 +foreach x of varlist $heckmanwage { +describe `x' +local varlabel : var label `x' +putexcel B`row' = ("`varlabel'") +local ylabel: var label temp_lnwage +putexcel A`row' = ("`ylabel'") +local row = `row'+1 +} +//-(put the label of "temp_lnwage" for _cons in wage eqn) +local ylabel: var label temp_lnwage +local row=5+$n_wagevars +putexcel A`row'= ("`ylabel'") + +//-labels of covariates for selection eqn +local row = 5+$n_wagevars+1 //"+1" because need to leave a cell for _cons for the wage eqn +foreach x of varlist $heckmanselection { +describe `x' +local varlabel : var label `x' +putexcel B`row' = ("`varlabel'") +local row = `row'+1 +} + +//Labels on the Excel columns (for e(V)) +//-labels of covariates for wage eqn + +local col=3 +foreach x of varlist $heckmanwage { +describe `x' +local varlabel : var label `x' +excelcol `col' //Convert a column index into a name of an Excel column (e.g. 3->C) +local colname `r(column)' //`colname'is now the name of Excel column +putexcel B`row' = ("`varlabel'") +local ylabel: var label temp_lnwage +putexcel `colname'3 = ("`ylabel'") +putexcel `colname'4 = ("`varlabel'") +local col = `col'+1 +} +//-(put the label of "temp_lnwage" for _cons in wage eqn) +local ylabel: var label temp_lnwage +local col=3+$n_wagevars +excelcol `col' //Convert a column index into a name of an Excel column (e.g. 3->C) +local colname `r(column)' //`colname'is now the name of Excel column +putexcel `colname'3= ("`ylabel'") +//-labels of covariates for selection eqn + +local col=3+$n_wagevars+1 //"+1" because need to leave a cell for _cons for the wage eqn +foreach x of varlist $heckmanselection { +describe `x' +local varlabel : var label `x' +excelcol `col' //Convert a column index into a name of an Excel column (e.g. 3->C) +local colname `r(column)' //`colname'is now the name of Excel column +putexcel `colname'4 = ("`varlabel'") +local col = `col'+1 +} +//for e(v) matrix row, put "_cons" as the last covariate for selection eqn (strangely, without this, the last covariate label will be the last covariate of the wage eqn, in this case "Northern Ireland". this does not happen in column labels) +//Also strangely, the following commands do not work if I put them before displaying labels for e(V) columns +if (`gender' == 0){ +putexcel set "$results_wi/wage_eV", sheet("female wage e(V)_group2") modify +} +else{ +putexcel set "$results_wi/wage_eV", sheet("male wage e(V)_group2") modify +} +global n_selectionvars: word count $heckmanselection //count the number of vars in list $heckmanselection +local n_selectionvars=5+$n_wagevars+1+$n_selectionvars +putexcel B`n_selectionvars'= ("_cons") +estimates save "$results_wi/heckman_`gender'_group2",replace //to save .ster files + + +eststo heckman_`gender'_group2 +//esttab heckman_`gender' using s_heckman_`gender'.csv, replace label cells(b(fmt(20)) t(par fmt(2))) plain //for simulation (plain, including all digits) +esttab heckman_`gender'_group2 using "$results_wi/heckman_`gender'_group2.csv", replace label cells(b(star fmt(a3)) t(par fmt(2))) //for writing (including at least three non-zero digits) + +*anti-log transformation +// gen double temp_u_`gender' = temp_lnwage - temp_lnw_`gender' if e(sample) //this line was moved forward when entering Excel of RMSE +sum temp_u_`gender'_group2 + +gen temp_wage_`gender'_group2 = exp(temp_lnw_`gender'_group2 + rnormal(0,r(sd))) // to avoid retransformation bias + +//R^2 +predict temp_lnw2_`gender'_group2 if e(sample), ycon +corr temp_lnwage temp_lnw2_`gender'_group2 if e(sample) +putexcel A48=("R^2") +putexcel B48=(r(rho)^2) //R^2 of wage eqn +gen temp_R2_lnwage_`gender'_group2=r(rho)^2 //store this variable for writing to tex later + +estadd scalar R2=temp_R2_lnwage_`gender'_group2 + +} //end of a loop for gender + +//esttab heckman_0 heckman_1 using heckman_01.csv, replace label cells(b(star fmt(a3)) t(par fmt(2))) //for writing (including at least three non-zero digits) +esttab heckman_1_group2 heckman_0_group2 using "$results_wi/heckman_10_group2.tex", replace label cells(b(star fmt(3))) stats(R2 N) nonumbers mtitles("Men" "Women") /// +collabels(none) /// +title(Determinants of hourly wages, men and women aged 16-75 (group 2: normal wages). Source: Our elaboration on PL EU-SILC input data for 2019 /// +\label{tab:wage-MF}) /// +addnote("*** Results significant at 0.1\%, ** 1\%, * 5\%.") //for writing tex including female and male(including at least three non-zero digits) + +esttab heckman_1_group2 heckman_0_group2 using "$results_wi/heckman_10_group2.csv", replace label cells(b(star fmt(3))) stats(R2 N) nonumbers mtitles("Men" "Women") /// +title(Determinants of hourly wages, men and women aged 16-75 (group2: normal wages). Source: Our elaboration on PL EU-SILC input data for 2019 /// +\label{tab:wage-MF}) /// +collabels(none) /// +addnote("*** Results significant at 0.1\%, ** 1\%, * 5\%.") //for writing csv including female and male(including at least three non-zero digits) + +//dummy of being included in the Heckman sample +gen temp_heckman_group2 =temp_heckman_0_group2 if dgn==0 & group2<. +replace temp_heckman_group2=temp_heckman_1_group2 if dgn==1 & group2<. + +*check sensitivity of wage predictions +sum temp_wage_0_group1 temp_wage_0_group2 if dgn==0 & temp_obs_wage>=800 & temp_obs_wage<900 +sum temp_wage_0_group1 temp_wage_0_group2 if dgn==0 & temp_obs_wage>=900 & temp_obs_wage<1000 + +sum temp_wage_1_group1 temp_wage_1_group2 if dgn==1 & temp_obs_wage>=800 & temp_obs_wage<900 +sum temp_wage_1_group1 temp_wage_1_group2 if dgn==1 & temp_obs_wage>=900 & temp_obs_wage<1000 + + +*=============================================================================== +* Output coefficients and VC Matrix to Excel +*=============================================================================== + +********************************************************** +* Sample: Working age (16-75) women with low wages +* DV: Log gross hourly wage +********************************************************** +* Prep storage +capture drop pred lwage_hour_hat wage_hour_hat esample pred_hourly_wage +gen lwage_hour_hat = . +gen wage_hour_hat = . +gen esample = . +gen pred_hourly_wage = . + + +************************************************************************************************************************************************************ +local covariates "dag temp_age2 temp_d_deh_M temp_d_deh_H temp_int_dehM_dag temp_int_dehH_dag liwwh temp_dhe_2 temp_dhe_3 temp_dhe_4 temp_dhe_5 temp_drgn1_2 temp_drgn1_3 temp_drgn1_4 temp_drgn1_5" //temp_d_deh_M temp_d_deh_H temp_int_dehM_dag temp_int_dehH_dag +local selection "temp_partnered temp_n_ch temp_d_ch2 dag temp_age2 temp_d_deh_M temp_d_deh_H temp_int_dehM_dag temp_int_dehH_dag liwwh temp_dhe_2 temp_dhe_3 temp_dhe_4 temp_dhe_5 temp_drgn1_2 temp_drgn1_3 temp_drgn1_4 temp_drgn1_5" //temp_d_deh_M temp_d_deh_H temp_int_dehM_dag temp_int_dehH_dag + +local filter "dgn==0 & temp_not_flexible==0 & group1<." +heckman temp_lnwage `covariates' if `filter', select(`selection') twostep + +/***************************************************************************/ +* Eigenvalue stability check + +* Extract variance-covariance matrix +matrix V = e(V) + +* Preserve data state +preserve + +* Export V to dataset +clear +svmat double V + +* Drop zero rows and columns +forvalues r = 1/2 { + egen rowsum = rowtotal(*) + drop if rowsum == 0 + drop rowsum + xpose, clear +} + +* Recreate trimmed VCV matrix +mkmat *, matrix(V_trimmed) + +restore + +* Eigen decomposition +matrix symeigen X lambda = V_trimmed + +* Largest eigenvalue +scalar max_eig = lambda[1,1] + +* Smallest-to-largest eigenvalue ratio +scalar min_ratio = lambda[1, colsof(lambda)] / max_eig + +* Check 1: near singularity +if max_eig < 1.0e-12 { + display as error "CRITICAL ERROR: Heckman VCV near singular" + display as error "Max eigenvalue = " max_eig + exit 999 +} + +* Check 2: ill-conditioning +if min_ratio < 1.0e-12 { + display as error "ERROR: Heckman VCV ill-conditioned" + display as error "Min/Max eigenvalue ratio = " min_ratio + exit 506 +} + +display "VCV stability check passed" +display "Max eigenvalue: " max_eig +display "Min/Max ratio: " min_ratio + +/***************************************************************************/ + +* Obtain predicted values (log wage) with selection correction + +predict pred if `filter', ycond // ycond -> include IMR in prediction to account for selection into employment +replace lwage_hour_hat = pred if `filter' + +gen in_sample_w1 = e(sample) + +* Correct bias when transforming from log to levels +cap drop epsilon +gen epsilon = rnormal()*e(sigma) + +replace pred_hourly_wage = exp(lwage_hour_hat + epsilon) if `filter' + + +twoway (hist temp_obs_wage if `filter', width(0.5) /// + lcolor(gs12) fcolor(gs12)) /// + (hist pred_hourly_wage if `filter' & (!missing(pred_hourly_wage)), width(0.5) /// + fcolor(none) lcolor(red)), /// + title("Gross Hourly Wage (Level)") /// + subtitle("Women, low wages") /// + xtitle("PLN") /// + legend(lab(1 "EU-SILC") lab(2 "Prediction")) /// + note("Notes: Sample condition `filter'", size(vsmall)) + +graph export "${results_wi}/W1_hist.png", replace + +graph drop _all + +sum temp_obs_wage if `filter' [aw=dwt] +sum pred_hourly_wage if `filter' & (!missing(pred_hourly_wage)) [aw=dwt] + + +* Save sample validation +save "${local_data}/W1_sample", replace + +cap drop pred epsilon + +* Formatted results +* Clean up matrix of estimates +* Note: Zeros values are eliminated +matrix b = e(b) +matrix V = e(V) + +* Store variance-covariance matrix +preserve + +putexcel set "${results_wi}/var_cov", sheet("var_cov") replace +putexcel A1 = matrix(V) + +import excel "${results_wi}/var_cov", sheet("var_cov") clear + +describe +local no_vars = `r(k)' + +forvalues i = 1/2 { + egen row_sum = rowtotal(*) + drop if row_sum == 0 + drop row_sum + xpose, clear +} + +mkmat v*, matrix(var) + +* Second stage +putexcel set "${results_wi}/reg_wages_raw", sheet("W1_raw") replace +putexcel C2 = matrix(var) + +restore + +* Store estimated coefficients +* Initialize a counter for non-zero coefficients +local non_zero_count = 0 +//local names : colnames b + +* Loop through each element in `b` to count non-zero coefficients +forvalues i = 1/`no_vars' { + if (b[1, `i'] != 0) { + local non_zero_count = `non_zero_count' + 1 + } +} + +* Create a new row vector to hold only non-zero coefficients +matrix nonzero_b = J(1, `non_zero_count', .) + +* Populate nonzero_b with non-zero coefficients from b +local index = 1 +forvalues i = 1/`no_vars' { + if (b[1, `i'] != 0) { + matrix nonzero_b[1, `index'] = b[1, `i'] + local index = `index' + 1 + } +} + +putexcel set "${results_wi}/reg_wages_raw", sheet("W1_raw") modify +putexcel B2 = matrix(nonzero_b') //, names nformat(number_d2) + +preserve + +import excel "${results_wi}/reg_wages_raw", sheet("W1_raw") /*firstrow*/ /// + clear +ds + +//define which cells are to be dropped +drop if C == 0 & D==0 // UPDATE +//drop A +drop S-AK // UPDATE + + +mkmat *, matrix(Women2) +matrix list Women2 + +putexcel set "${results_wi}/reg_wages", sheet("W1") modify +putexcel B2 = matrix(Women2) + +restore + + +* Labelling +putexcel set "${results_wi}/reg_wages", sheet("W1") modify + +local var_list Dag Dag_sq /// +Deh_c3_Medium Deh_c3_High /// +Deh_c3_Medium_Dag Deh_c3_High_Dag /// +Liwwh /// +Dhe_Fair Dhe_Good Dhe_VeryGood Dhe_Excellent /// +PL4 PL5 PL6 PL10 /// +Constant InverseMillsRatio + + +putexcel A1 = ("REGRESSOR") +putexcel B1 = ("COEFFICIENT") + +local i = 1 +foreach var in `var_list' { + local ++i + + putexcel A`i' = ("`var'") + +} + +local i = 2 +foreach var in `var_list' { + local ++i + + if `i' <= 26 { + local letter = char(64 + `i') // Convert 1=A, 2=B, ..., 26=Z + putexcel `letter'1 = ("`var'") + } + else { + local first = char(64 + int((`i' - 1) / 26)) // First letter: A-Z + local second = char(65 + mod((`i' - 1), 26)) // Second letter: A-Z + putexcel `first'`second'1 = ("`var'") // Correctly places AA-ZZ + } +} + + +* First stage +preserve + +import excel "${results_wi}/reg_wages_raw", sheet("W1_raw") /*firstrow*/ /// + clear +ds + +drop if S== 0 // UPDATE +//drop A +drop C-R // UPDATE +drop AL // UPDATE + + +mkmat *, matrix(Women2) +matrix list Women2 + +putexcel set "${results_wi}/reg_employment_selection", sheet("W1-sel") modify +putexcel B2 = matrix(Women2) + +restore + +* Labelling +putexcel set "${results_wi}/reg_employment_selection", sheet("W1-sel") modify + +local var_list Dcpst_Partnered Children D_Children2 /// +Dag Dag_sq /// +Deh_c3_Medium Deh_c3_High /// +Deh_c3_Medium_Dag Deh_c3_High_Dag /// +Liwwh /// +Dhe_Fair Dhe_Good Dhe_VeryGood Dhe_Excellent /// +PL4 PL5 PL6 PL10 /// +Constant + +putexcel A1 = ("REGRESSOR") +putexcel B1 = ("COEFFICIENT") + +local i = 1 +foreach var in `var_list' { + local ++i + + putexcel A`i' = ("`var'") + +} + +local i = 2 +foreach var in `var_list' { + local ++i + + if `i' <= 26 { + local letter = char(64 + `i') // Convert 1=A, 2=B, ..., 26=Z + putexcel `letter'1 = ("`var'") + } + else { + local first = char(64 + int((`i' - 1) / 26)) // First letter: A-Z + local second = char(65 + mod((`i' - 1), 26)) // Second letter: A-Z + putexcel `first'`second'1 = ("`var'") // Correctly places AA-ZZ + } +} + +cap drop lambda + + +* Calculate RMSE +cap drop residuals squared_residuals +gen residuals = temp_lnwage - lwage_hour_hat +gen squared_residuals = residuals^2 + +preserve +keep if `filter' +sum squared_residuals +di "RMSE for women with low wages: " sqrt(r(mean)) +putexcel set "${results_wi}/reg_RMSE_wages.xlsx", sheet("PL") modify +putexcel A1=("REGRESSOR") B1=("COEFFICIENT") /// +A2=("W1") B2=(sqrt(r(mean))) +restore + + +********************************************************** +* Sample: Working age (16-75) men with low wages +* DV: Log gross hourly wage +********************************************************** +* Prep storage +capture drop pred lwage_hour_hat wage_hour_hat esample pred_hourly_wage +gen lwage_hour_hat = . +gen wage_hour_hat = . +gen esample = . +gen pred_hourly_wage = . + + +************************************************************************************************************************************************************ +local covariates "dag temp_age2 temp_d_deh_M temp_d_deh_H temp_int_dehM_dag temp_int_dehH_dag liwwh temp_dhe_2 temp_dhe_3 temp_dhe_4 temp_dhe_5 temp_drgn1_2 temp_drgn1_3 temp_drgn1_4 temp_drgn1_5" //temp_d_deh_M temp_d_deh_H temp_int_dehM_dag temp_int_dehH_dag +local selection "temp_partnered temp_n_ch temp_d_ch2 dag temp_age2 temp_d_deh_M temp_d_deh_H temp_int_dehM_dag temp_int_dehH_dag liwwh temp_dhe_2 temp_dhe_3 temp_dhe_4 temp_dhe_5 temp_drgn1_2 temp_drgn1_3 temp_drgn1_4 temp_drgn1_5" //temp_d_deh_M temp_d_deh_H temp_int_dehM_dag temp_int_dehH_dag + +local filter "dgn==1 & temp_not_flexible==0 & group1<." +heckman temp_lnwage `covariates' if `filter', select(`selection') twostep + +/***************************************************************************/ +* Eigenvalue stability check + +* Extract variance-covariance matrix +matrix V = e(V) + +* Preserve data state +preserve + +* Export V to dataset +clear +svmat double V + +* Drop zero rows and columns +forvalues r = 1/2 { + egen rowsum = rowtotal(*) + drop if rowsum == 0 + drop rowsum + xpose, clear +} + +* Recreate trimmed VCV matrix +mkmat *, matrix(V_trimmed) + +restore + +* Eigen decomposition +matrix symeigen X lambda = V_trimmed + +* Largest eigenvalue +scalar max_eig = lambda[1,1] + +* Smallest-to-largest eigenvalue ratio +scalar min_ratio = lambda[1, colsof(lambda)] / max_eig + +* Check 1: near singularity +if max_eig < 1.0e-12 { + display as error "CRITICAL ERROR: Heckman VCV near singular" + display as error "Max eigenvalue = " max_eig + exit 999 +} + +* Check 2: ill-conditioning +if min_ratio < 1.0e-12 { + display as error "ERROR: Heckman VCV ill-conditioned" + display as error "Min/Max eigenvalue ratio = " min_ratio + exit 506 +} + +display "VCV stability check passed" +display "Max eigenvalue: " max_eig +display "Min/Max ratio: " min_ratio + +/***************************************************************************/ + +* Obtain predicted values (log wage) with selection correction + +predict pred if `filter', ycond // ycond -> include IMR in prediction to account for selection into employment +replace lwage_hour_hat = pred if `filter' + +gen in_sample_m1 = e(sample) + +* Correct bias when transforming from log to levels +cap drop epsilon +gen epsilon = rnormal()*e(sigma) + +replace pred_hourly_wage = exp(lwage_hour_hat + epsilon) if `filter' + + +twoway (hist temp_obs_wage if `filter', width(0.5) /// + lcolor(gs12) fcolor(gs12)) /// + (hist pred_hourly_wage if `filter' & (!missing(pred_hourly_wage)), width(0.5) /// + fcolor(none) lcolor(red)), /// + title("Gross Hourly Wage (Level)") /// + subtitle("Men, low wages") /// + xtitle("PLN") /// + legend(lab(1 "EU-SILC") lab(2 "Prediction")) /// + note("Notes: Sample condition `filter'", size(vsmall)) + +graph export "${results_wi}/M1_hist.png", replace + +graph drop _all + +sum temp_obs_wage if `filter' [aw=dwt] +sum pred_hourly_wage if `filter' & (!missing(pred_hourly_wage)) [aw=dwt] + + +* Save sample validation +save "${local_data}/M2_sample", replace + +cap drop pred epsilon + +* Formatted results +* Clean up matrix of estimates +* Note: Zeros values are eliminated +matrix b = e(b) +matrix V = e(V) + +* Store variance-covariance matrix +preserve + +putexcel set "${results_wi}/var_cov", sheet("var_cov") replace +putexcel A1 = matrix(V) + +import excel "${results_wi}/var_cov", sheet("var_cov") clear + +describe +local no_vars = `r(k)' + +forvalues i = 1/2 { + egen row_sum = rowtotal(*) + drop if row_sum == 0 + drop row_sum + xpose, clear +} + +mkmat v*, matrix(var) + +* Second stage +putexcel set "${results_wi}/reg_wages_raw", sheet("M1_raw") replace +putexcel C2 = matrix(var) + +restore + +* Store estimated coefficients +* Initialize a counter for non-zero coefficients +local non_zero_count = 0 +//local names : colnames b + +* Loop through each element in `b` to count non-zero coefficients +forvalues i = 1/`no_vars' { + if (b[1, `i'] != 0) { + local non_zero_count = `non_zero_count' + 1 + } +} + +* Create a new row vector to hold only non-zero coefficients +matrix nonzero_b = J(1, `non_zero_count', .) + +* Populate nonzero_b with non-zero coefficients from b +local index = 1 +forvalues i = 1/`no_vars' { + if (b[1, `i'] != 0) { + matrix nonzero_b[1, `index'] = b[1, `i'] + local index = `index' + 1 + } +} + +putexcel set "${results_wi}/reg_wages_raw", sheet("M1_raw") modify +putexcel B2 = matrix(nonzero_b') //, names nformat(number_d2) + +preserve + +import excel "${results_wi}/reg_wages_raw", sheet("M1_raw") /*firstrow*/ /// + clear +ds + +//define which cells are to be dropped +drop if C == 0 & D==0 // UPDATE +//drop A +drop S-AK // UPDATE + + +mkmat *, matrix(Women2) +matrix list Women2 + +putexcel set "${results_wi}/reg_wages", sheet("M1") modify +putexcel B2 = matrix(Women2) + +restore + + +* Labelling +putexcel set "${results_wi}/reg_wages", sheet("M1") modify + +local var_list Dag Dag_sq /// +Deh_c3_Medium Deh_c3_High /// +Deh_c3_Medium_Dag Deh_c3_High_Dag /// +Liwwh /// +Dhe_Fair Dhe_Good Dhe_VeryGood Dhe_Excellent /// +PL4 PL5 PL6 PL10 /// +Constant InverseMillsRatio + + +putexcel A1 = ("REGRESSOR") +putexcel B1 = ("COEFFICIENT") + +local i = 1 +foreach var in `var_list' { + local ++i + + putexcel A`i' = ("`var'") + +} + +local i = 2 +foreach var in `var_list' { + local ++i + + if `i' <= 26 { + local letter = char(64 + `i') // Convert 1=A, 2=B, ..., 26=Z + putexcel `letter'1 = ("`var'") + } + else { + local first = char(64 + int((`i' - 1) / 26)) // First letter: A-Z + local second = char(65 + mod((`i' - 1), 26)) // Second letter: A-Z + putexcel `first'`second'1 = ("`var'") // Correctly places AA-ZZ + } +} + + +* First stage +preserve + +import excel "${results_wi}/reg_wages_raw", sheet("M1_raw") /*firstrow*/ /// + clear +ds + +drop if S== 0 // UPDATE +//drop A +drop C-R // UPDATE +drop AL // UPDATE + + +mkmat *, matrix(Women2) +matrix list Women2 + +putexcel set "${results_wi}/reg_employment_selection", sheet("M1-sel") modify +putexcel B2 = matrix(Women2) + +restore + +* Labelling +putexcel set "${results_wi}/reg_employment_selection", sheet("M1-sel") modify + +local var_list Dcpst_Partnered Children D_Children2 /// +Dag Dag_sq /// +Deh_c3_Medium Deh_c3_High /// +Deh_c3_Medium_Dag Deh_c3_High_Dag /// +Liwwh /// +Dhe_Fair Dhe_Good Dhe_VeryGood Dhe_Excellent /// +PL4 PL5 PL6 PL10 /// +Constant + +putexcel A1 = ("REGRESSOR") +putexcel B1 = ("COEFFICIENT") + +local i = 1 +foreach var in `var_list' { + local ++i + + putexcel A`i' = ("`var'") + +} + +local i = 2 +foreach var in `var_list' { + local ++i + + if `i' <= 26 { + local letter = char(64 + `i') // Convert 1=A, 2=B, ..., 26=Z + putexcel `letter'1 = ("`var'") + } + else { + local first = char(64 + int((`i' - 1) / 26)) // First letter: A-Z + local second = char(65 + mod((`i' - 1), 26)) // Second letter: A-Z + putexcel `first'`second'1 = ("`var'") // Correctly places AA-ZZ + } +} + +cap drop lambda + + +* Calculate RMSE +cap drop residuals squared_residuals +gen residuals = temp_lnwage - lwage_hour_hat +gen squared_residuals = residuals^2 + +preserve +keep if `filter' +sum squared_residuals +di "RMSE for men with low wages: " sqrt(r(mean)) +putexcel set "${results_wi}/reg_RMSE_wages.xlsx", sheet("PL") modify +putexcel A1=("REGRESSOR") B1=("COEFFICIENT") /// +A3=("M1") B3=(sqrt(r(mean))) +restore + + + +********************************************************** +* Sample: Working age (16-75) women with normal wages +* DV: Log gross hourly wage +********************************************************** +* Prep storage +capture drop pred lwage_hour_hat wage_hour_hat esample pred_hourly_wage +gen lwage_hour_hat = . +gen wage_hour_hat = . +gen esample = . +gen pred_hourly_wage = . + + +************************************************************************************************************************************************************ +local covariates "dag temp_age2 temp_d_deh_M temp_d_deh_H temp_int_dehM_dag temp_int_dehH_dag liwwh temp_dhe_2 temp_dhe_3 temp_dhe_4 temp_dhe_5 temp_drgn1_2 temp_drgn1_3 temp_drgn1_4 temp_drgn1_5" //temp_d_deh_M temp_d_deh_H temp_int_dehM_dag temp_int_dehH_dag +local selection "temp_partnered temp_n_ch temp_d_ch2 dag temp_age2 temp_d_deh_M temp_d_deh_H temp_int_dehM_dag temp_int_dehH_dag liwwh temp_dhe_2 temp_dhe_3 temp_dhe_4 temp_dhe_5 temp_drgn1_2 temp_drgn1_3 temp_drgn1_4 temp_drgn1_5" //temp_d_deh_M temp_d_deh_H temp_int_dehM_dag temp_int_dehH_dag + +local filter "dgn==0 & temp_not_flexible==0 & group2<." +heckman temp_lnwage `covariates' if `filter', select(`selection') twostep + +/***************************************************************************/ +* Eigenvalue stability check + +* Extract variance-covariance matrix +matrix V = e(V) + +* Preserve data state +preserve + +* Export V to dataset +clear +svmat double V + +* Drop zero rows and columns +forvalues r = 1/2 { + egen rowsum = rowtotal(*) + drop if rowsum == 0 + drop rowsum + xpose, clear +} + +* Recreate trimmed VCV matrix +mkmat *, matrix(V_trimmed) + +restore + +* Eigen decomposition +matrix symeigen X lambda = V_trimmed + +* Largest eigenvalue +scalar max_eig = lambda[1,1] + +* Smallest-to-largest eigenvalue ratio +scalar min_ratio = lambda[1, colsof(lambda)] / max_eig + +* Check 1: near singularity +if max_eig < 1.0e-12 { + display as error "CRITICAL ERROR: Heckman VCV near singular" + display as error "Max eigenvalue = " max_eig + exit 999 +} + +* Check 2: ill-conditioning +if min_ratio < 1.0e-12 { + display as error "ERROR: Heckman VCV ill-conditioned" + display as error "Min/Max eigenvalue ratio = " min_ratio + exit 506 +} + +display "VCV stability check passed" +display "Max eigenvalue: " max_eig +display "Min/Max ratio: " min_ratio + +/***************************************************************************/ + +* Obtain predicted values (log wage) with selection correction + +predict pred if `filter', ycond // ycond -> include IMR in prediction to account for selection into employment +replace lwage_hour_hat = pred if `filter' + +gen in_sample_w2 = e(sample) + +* Correct bias when transforming from log to levels +cap drop epsilon +gen epsilon = rnormal()*e(sigma) + +replace pred_hourly_wage = exp(lwage_hour_hat + epsilon) if `filter' + + +twoway (hist temp_obs_wage if `filter', width(0.5) /// + lcolor(gs12) fcolor(gs12)) /// + (hist pred_hourly_wage if `filter' & (!missing(pred_hourly_wage)), width(0.5) /// + fcolor(none) lcolor(red)), /// + title("Gross Hourly Wage (Level)") /// + subtitle("Women, normal wages") /// + xtitle("PLN") /// + legend(lab(1 "EU-SILC") lab(2 "Prediction")) /// + note("Notes: Sample condition `filter'", size(vsmall)) + +graph export "${results_wi}/W2_hist.png", replace + +graph drop _all + +sum temp_obs_wage if `filter' [aw=dwt] +sum pred_hourly_wage if `filter' & (!missing(pred_hourly_wage)) [aw=dwt] + + +* Save sample validation +save "${local_data}/W2_sample", replace + +cap drop pred epsilon + +* Formatted results +* Clean up matrix of estimates +* Note: Zeros values are eliminated +matrix b = e(b) +matrix V = e(V) + +* Store variance-covariance matrix +preserve + +putexcel set "${results_wi}/var_cov", sheet("var_cov") replace +putexcel A1 = matrix(V) + +import excel "${results_wi}/var_cov", sheet("var_cov") clear + +describe +local no_vars = `r(k)' + +forvalues i = 1/2 { + egen row_sum = rowtotal(*) + drop if row_sum == 0 + drop row_sum + xpose, clear +} + +mkmat v*, matrix(var) + +* Second stage +putexcel set "${results_wi}/reg_wages_raw", sheet("W2_raw") replace +putexcel C2 = matrix(var) + +restore + +* Store estimated coefficients +* Initialize a counter for non-zero coefficients +local non_zero_count = 0 +//local names : colnames b + +* Loop through each element in `b` to count non-zero coefficients +forvalues i = 1/`no_vars' { + if (b[1, `i'] != 0) { + local non_zero_count = `non_zero_count' + 1 + } +} + +* Create a new row vector to hold only non-zero coefficients +matrix nonzero_b = J(1, `non_zero_count', .) + +* Populate nonzero_b with non-zero coefficients from b +local index = 1 +forvalues i = 1/`no_vars' { + if (b[1, `i'] != 0) { + matrix nonzero_b[1, `index'] = b[1, `i'] + local index = `index' + 1 + } +} + +putexcel set "${results_wi}/reg_wages_raw", sheet("W2_raw") modify +putexcel B2 = matrix(nonzero_b') //, names nformat(number_d2) + +preserve + +import excel "${results_wi}/reg_wages_raw", sheet("W2_raw") /*firstrow*/ /// + clear +ds + +//define which cells are to be dropped +drop if C == 0 & D==0 // UPDATE +//drop A +drop S-AK // UPDATE + + +mkmat *, matrix(Women2) +matrix list Women2 + +putexcel set "${results_wi}/reg_wages", sheet("W2") modify +putexcel B2 = matrix(Women2) + +restore + + +* Labelling +putexcel set "${results_wi}/reg_wages", sheet("W2") modify + +local var_list Dag Dag_sq /// +Deh_c3_Medium Deh_c3_High /// +Deh_c3_Medium_Dag Deh_c3_High_Dag /// +Liwwh /// +Dhe_Fair Dhe_Good Dhe_VeryGood Dhe_Excellent /// +PL4 PL5 PL6 PL10 /// +Constant InverseMillsRatio + + +putexcel A1 = ("REGRESSOR") +putexcel B1 = ("COEFFICIENT") + +local i = 1 +foreach var in `var_list' { + local ++i + + putexcel A`i' = ("`var'") + +} + +local i = 2 +foreach var in `var_list' { + local ++i + + if `i' <= 26 { + local letter = char(64 + `i') // Convert 1=A, 2=B, ..., 26=Z + putexcel `letter'1 = ("`var'") + } + else { + local first = char(64 + int((`i' - 1) / 26)) // First letter: A-Z + local second = char(65 + mod((`i' - 1), 26)) // Second letter: A-Z + putexcel `first'`second'1 = ("`var'") // Correctly places AA-ZZ + } +} + + +* First stage +preserve + +import excel "${results_wi}/reg_wages_raw", sheet("W2_raw") /*firstrow*/ /// + clear +ds + +drop if S== 0 // UPDATE +//drop A +drop C-R // UPDATE +drop AL // UPDATE + + +mkmat *, matrix(Women2) +matrix list Women2 + +putexcel set "${results_wi}/reg_employment_selection", sheet("W2-sel") modify +putexcel B2 = matrix(Women2) + +restore + +* Labelling +putexcel set "${results_wi}/reg_employment_selection", sheet("W2-sel") modify + +local var_list Dcpst_Partnered Children D_Children2 /// +Dag Dag_sq /// +Deh_c3_Medium Deh_c3_High /// +Deh_c3_Medium_Dag Deh_c3_High_Dag /// +Liwwh /// +Dhe_Fair Dhe_Good Dhe_VeryGood Dhe_Excellent /// +PL4 PL5 PL6 PL10 /// +Constant + +putexcel A1 = ("REGRESSOR") +putexcel B1 = ("COEFFICIENT") + +local i = 1 +foreach var in `var_list' { + local ++i + + putexcel A`i' = ("`var'") + +} + +local i = 2 +foreach var in `var_list' { + local ++i + + if `i' <= 26 { + local letter = char(64 + `i') // Convert 1=A, 2=B, ..., 26=Z + putexcel `letter'1 = ("`var'") + } + else { + local first = char(64 + int((`i' - 1) / 26)) // First letter: A-Z + local second = char(65 + mod((`i' - 1), 26)) // Second letter: A-Z + putexcel `first'`second'1 = ("`var'") // Correctly places AA-ZZ + } +} + +cap drop lambda + + +* Calculate RMSE +cap drop residuals squared_residuals +gen residuals = temp_lnwage - lwage_hour_hat +gen squared_residuals = residuals^2 + +preserve +keep if `filter' +sum squared_residuals +di "RMSE for women with normal wages: " sqrt(r(mean)) +putexcel set "${results_wi}/reg_RMSE_wages.xlsx", sheet("PL") modify +putexcel A1=("REGRESSOR") B1=("COEFFICIENT") /// +A4=("W2") B4=(sqrt(r(mean))) +restore + + +********************************************************** +* Sample: Working age (16-75) men with normal wages +* DV: Log gross hourly wage +********************************************************** +* Prep storage +capture drop pred lwage_hour_hat wage_hour_hat esample pred_hourly_wage +gen lwage_hour_hat = . +gen wage_hour_hat = . +gen esample = . +gen pred_hourly_wage = . + + +************************************************************************************************************************************************************ +local covariates "dag temp_age2 temp_d_deh_M temp_d_deh_H temp_int_dehM_dag temp_int_dehH_dag liwwh temp_dhe_2 temp_dhe_3 temp_dhe_4 temp_dhe_5 temp_drgn1_2 temp_drgn1_3 temp_drgn1_4 temp_drgn1_5" //temp_d_deh_M temp_d_deh_H temp_int_dehM_dag temp_int_dehH_dag +local selection "temp_partnered temp_n_ch temp_d_ch2 dag temp_age2 temp_d_deh_M temp_d_deh_H temp_int_dehM_dag temp_int_dehH_dag liwwh temp_dhe_2 temp_dhe_3 temp_dhe_4 temp_dhe_5 temp_drgn1_2 temp_drgn1_3 temp_drgn1_4 temp_drgn1_5" //temp_d_deh_M temp_d_deh_H temp_int_dehM_dag temp_int_dehH_dag + +local filter "dgn==1 & temp_not_flexible==0 & group2<." +heckman temp_lnwage `covariates' if `filter', select(`selection') twostep + +/***************************************************************************/ +* Eigenvalue stability check + +* Extract variance-covariance matrix +matrix V = e(V) + +* Preserve data state +preserve + +* Export V to dataset +clear +svmat double V + +* Drop zero rows and columns +forvalues r = 1/2 { + egen rowsum = rowtotal(*) + drop if rowsum == 0 + drop rowsum + xpose, clear +} + +* Recreate trimmed VCV matrix +mkmat *, matrix(V_trimmed) + +restore + +* Eigen decomposition +matrix symeigen X lambda = V_trimmed + +* Largest eigenvalue +scalar max_eig = lambda[1,1] + +* Smallest-to-largest eigenvalue ratio +scalar min_ratio = lambda[1, colsof(lambda)] / max_eig + +* Check 1: near singularity +if max_eig < 1.0e-12 { + display as error "CRITICAL ERROR: Heckman VCV near singular" + display as error "Max eigenvalue = " max_eig + exit 999 +} + +* Check 2: ill-conditioning +if min_ratio < 1.0e-12 { + display as error "ERROR: Heckman VCV ill-conditioned" + display as error "Min/Max eigenvalue ratio = " min_ratio + exit 506 +} + +display "VCV stability check passed" +display "Max eigenvalue: " max_eig +display "Min/Max ratio: " min_ratio + +/***************************************************************************/ + +* Obtain predicted values (log wage) with selection correction + +predict pred if `filter', ycond // ycond -> include IMR in prediction to account for selection into employment +replace lwage_hour_hat = pred if `filter' + +gen in_sample_m2 = e(sample) + +* Correct bias when transforming from log to levels +cap drop epsilon +gen epsilon = rnormal()*e(sigma) + +replace pred_hourly_wage = exp(lwage_hour_hat + epsilon) if `filter' + + +twoway (hist temp_obs_wage if `filter', width(0.5) /// + lcolor(gs12) fcolor(gs12)) /// + (hist pred_hourly_wage if `filter' & (!missing(pred_hourly_wage)), width(0.5) /// + fcolor(none) lcolor(red)), /// + title("Gross Hourly Wage (Level)") /// + subtitle("Men") /// + xtitle("PLN") /// + legend(lab(1 "EU-SILC") lab(2 "Prediction")) /// + note("Notes: Sample condition `filter'", size(vsmall)) + +graph export "${results_wi}/M2_hist.png", replace + +graph drop _all + +sum temp_obs_wage if `filter' [aw=dwt] +sum pred_hourly_wage if `filter' & (!missing(pred_hourly_wage)) [aw=dwt] + + +* Save sample validation +save "${local_data}/M2_sample", replace + +cap drop pred epsilon + +* Formatted results +* Clean up matrix of estimates +* Note: Zeros values are eliminated +matrix b = e(b) +matrix V = e(V) + +* Store variance-covariance matrix +preserve + +putexcel set "${results_wi}/var_cov", sheet("var_cov") replace +putexcel A1 = matrix(V) + +import excel "${results_wi}/var_cov", sheet("var_cov") clear + +describe +local no_vars = `r(k)' + +forvalues i = 1/2 { + egen row_sum = rowtotal(*) + drop if row_sum == 0 + drop row_sum + xpose, clear +} + +mkmat v*, matrix(var) + +* Second stage +putexcel set "${results_wi}/reg_wages_raw", sheet("M2_raw") replace +putexcel C2 = matrix(var) + +restore + +* Store estimated coefficients +* Initialize a counter for non-zero coefficients +local non_zero_count = 0 +//local names : colnames b + +* Loop through each element in `b` to count non-zero coefficients +forvalues i = 1/`no_vars' { + if (b[1, `i'] != 0) { + local non_zero_count = `non_zero_count' + 1 + } +} + +* Create a new row vector to hold only non-zero coefficients +matrix nonzero_b = J(1, `non_zero_count', .) + +* Populate nonzero_b with non-zero coefficients from b +local index = 1 +forvalues i = 1/`no_vars' { + if (b[1, `i'] != 0) { + matrix nonzero_b[1, `index'] = b[1, `i'] + local index = `index' + 1 + } +} + +putexcel set "${results_wi}/reg_wages_raw", sheet("M2_raw") modify +putexcel B2 = matrix(nonzero_b') //, names nformat(number_d2) + +preserve + +import excel "${results_wi}/reg_wages_raw", sheet("M2_raw") /*firstrow*/ /// + clear +ds + +//define which cells are to be dropped +drop if C == 0 & D==0 // UPDATE +//drop A +drop S-AK // UPDATE + + +mkmat *, matrix(Women2) +matrix list Women2 + +putexcel set "${results_wi}/reg_wages", sheet("M2") modify +putexcel B2 = matrix(Women2) + +restore + + +* Labelling +putexcel set "${results_wi}/reg_wages", sheet("M2") modify + +local var_list Dag Dag_sq /// +Deh_c3_Medium Deh_c3_High /// +Deh_c3_Medium_Dag Deh_c3_High_Dag /// +Liwwh /// +Dhe_Fair Dhe_Good Dhe_VeryGood Dhe_Excellent /// +PL4 PL5 PL6 PL10 /// +Constant InverseMillsRatio + + +putexcel A1 = ("REGRESSOR") +putexcel B1 = ("COEFFICIENT") + +local i = 1 +foreach var in `var_list' { + local ++i + + putexcel A`i' = ("`var'") + +} + +local i = 2 +foreach var in `var_list' { + local ++i + + if `i' <= 26 { + local letter = char(64 + `i') // Convert 1=A, 2=B, ..., 26=Z + putexcel `letter'1 = ("`var'") + } + else { + local first = char(64 + int((`i' - 1) / 26)) // First letter: A-Z + local second = char(65 + mod((`i' - 1), 26)) // Second letter: A-Z + putexcel `first'`second'1 = ("`var'") // Correctly places AA-ZZ + } +} + + +* First stage +preserve + +import excel "${results_wi}/reg_wages_raw", sheet("M2_raw") /*firstrow*/ /// + clear +ds + +drop if S== 0 // UPDATE +//drop A +drop C-R // UPDATE +drop AL // UPDATE + + +mkmat *, matrix(Women2) +matrix list Women2 + +putexcel set "${results_wi}/reg_employment_selection", sheet("M2-sel") modify +putexcel B2 = matrix(Women2) + +restore + +* Labelling +putexcel set "${results_wi}/reg_employment_selection", sheet("M2-sel") modify + +local var_list Dcpst_Partnered Children D_Children2 /// +Dag Dag_sq /// +Deh_c3_Medium Deh_c3_High /// +Deh_c3_Medium_Dag Deh_c3_High_Dag /// +Liwwh /// +Dhe_Fair Dhe_Good Dhe_VeryGood Dhe_Excellent /// +PL4 PL5 PL6 PL10 /// +Constant + +putexcel A1 = ("REGRESSOR") +putexcel B1 = ("COEFFICIENT") + +local i = 1 +foreach var in `var_list' { + local ++i + + putexcel A`i' = ("`var'") + +} + +local i = 2 +foreach var in `var_list' { + local ++i + + if `i' <= 26 { + local letter = char(64 + `i') // Convert 1=A, 2=B, ..., 26=Z + putexcel `letter'1 = ("`var'") + } + else { + local first = char(64 + int((`i' - 1) / 26)) // First letter: A-Z + local second = char(65 + mod((`i' - 1), 26)) // Second letter: A-Z + putexcel `first'`second'1 = ("`var'") // Correctly places AA-ZZ + } +} + +cap drop lambda + + +* Calculate RMSE +cap drop residuals squared_residuals +gen residuals = temp_lnwage - lwage_hour_hat +gen squared_residuals = residuals^2 + +preserve +keep if `filter' +sum squared_residuals +di "RMSE for men with normal wages: " sqrt(r(mean)) +putexcel set "${results_wi}/reg_RMSE_wages.xlsx", sheet("PL") modify +putexcel A1=("REGRESSOR") B1=("COEFFICIENT") /// +A5=("M2") B5=(sqrt(r(mean))) +restore + + + +*======================================================================= +* Two ways of wage imputations +*======================================================================= + +*------------------------------------------------------------ +* // @@@ WAGE IMPUTATION METHOD #wage1 @@@ +* make predicted wage=yivwg for everyone +*------------------------------------------------------------ +/*//make predicted wage=yivwg (yivwg: name for predicted hourly wage in UKMOD) +cap gen yivwg=temp_wage_0_group1 if dgn==0 & group1==1 //women with low wages +replace yivwg=temp_wage_1_group1 if dgn==1 & group1==1 //men with low wages +replace yivwg=temp_wage_0_group2 if dgn==0 & group2==1 //women with high wages +replace yivwg=temp_wage_1_group2 if dgn==1 & group2==1 //men with high wages +for non-working take group 2 prediction +replace yivwg=temp_wage_0_group2 if dgn==0 & nonworking==1 +replace yivwg=temp_wage_1_group2 if dgn==1 & nonworking==1 +*/ + +/*Different Wage Structures: By splitting the workers into two wage groups, we are recognizing that the wage determination process might differ significantly between those reporting low wages and those earning higher wages. +As a result, predicting wages for the non-employed needs to take both structures into account. +Reweighting Using Probabilities: +1/ When we compute the probability of being employed from each subsample, we capture the likelihood that a non-employed individual would "belong" to either group (low-wage or high-wage). +2/ Reweighting the predicted wages using these probabilities can be thought of as a weighted average of the potential wages from both models. +This accounts for uncertainty about which wage group a non-employed individual might fall into if they were employed. +3/ Normalization: Dividing by the sum of the two probabilities ensures that the weights add up to 1, maintaining the coherence of the predicted wage distribution. +*/ + +*predicted wages for everyone incl working using predictions from equation 1 +cap drop yivwg1 +gen yivwg1 =. +replace yivwg1 = temp_wage_0_group1 if dgn==0 +replace yivwg1 = temp_wage_1_group1 if dgn==1 +sum yivwg1 + +*predicted wages for everyone incl working using predictions from equation 2 +cap drop yivwg2 +gen yivwg2 =. +replace yivwg2 = temp_wage_0_group2 if dgn==0 +replace yivwg2 = temp_wage_1_group2 if dgn==1 +sum yivwg2 + + +*predicted wages for everyone incl working using mixed predictions +foreach gender in 0 1 { +gen weight_`gender'_group1 = temp_pr_`gender'_group1 / (temp_pr_`gender'_group1 + temp_pr_`gender'_group2) +gen weight_`gender'_group2 = temp_pr_`gender'_group2 / (temp_pr_`gender'_group1 + temp_pr_`gender'_group2) +} +cap drop yivwg +gen yivwg =. +replace yivwg = weight_0_group1*temp_wage_0_group1 + weight_0_group2*temp_wage_0_group2 if dgn==0 //weight low * wage low + weight high * wage high +replace yivwg = weight_1_group1*temp_wage_1_group1 + weight_1_group2*temp_wage_1_group2 if dgn==1 //weight low * wage low + weight high * wage high + +sum yivwg if group1==1 +sum yivwg if group2==1 +sum yivwg if nonworking==1 + +assert yivwg!=. + + +*Trim predicted wage to get rid of outliers??? +/*centile yivwg, centile(1 2 3 4 5 95 96 97 98 99) +return list +replace yivwg = `r(c_1)' if yivwg <= `r(c_1)' +replace yivwg = `r(c_10)' if yivwg >= `r(c_10)' +*/ +centile temp_obs_wage if lhw>0, centile(1 2 3 4 5 95 96 97 98 99) +return list +replace yivwg1 = `r(c_10)' if yivwg1 >= `r(c_10)' +replace yivwg2 = `r(c_10)' if yivwg2 >= `r(c_10)' +replace yivwg = `r(c_10)' if yivwg >= `r(c_10)' +sum yivwg1 if yivwg<. +sum yivwg2 if yivwg<. +sum yivwg if yivwg<. + + +//gen temp_obs_wage=temp_y/(lhw*4.3) +//observed wages vs predicted wages +su temp_obs_wage yivwg if temp_work==1 & temp_heckman_group1==1 & yivwg!=-1 +bysort dgn:su temp_obs_wage yivwg if temp_work==1 & temp_heckman_group1==1 & yivwg!=-1 +//observed wages vs predicted wages +su temp_obs_wage yivwg if temp_work==1 & temp_heckman_group2==1 & yivwg!=-1 +bysort dgn:su temp_obs_wage yivwg if temp_work==1 & temp_heckman_group2==1 & yivwg!=-1 + + +********************************************* +* Graph of predicted wage vs. observed wage * +********************************************* +version 14 +************** +*scatterplot * +************** +*graph for both groups +foreach gender in 0 1 { //beginning of gender loop + + twoway(scatter yivwg temp_obs_wage if dgn==`gender' & (temp_heckman_`gender'_group1 == 1 | temp_heckman_`gender'_group2==1) & yivwg>0)(line temp_obs_wage temp_obs_wage if dgn==`gender') + graph export "$results_wi/wages_scatter_`gender'.png", as(png) replace +*graph for group 1 + twoway(scatter yivwg1 temp_obs_wage if dgn==`gender' & (temp_heckman_`gender'_group1 == 1) & yivwg1>0)(line temp_obs_wage temp_obs_wage if dgn==`gender') + graph export "$results_wi/wages_scatter_`gender'_group1.png", as(png) replace +*graph for group 2 + twoway(scatter yivwg2 temp_obs_wage if dgn==`gender' & (temp_heckman_`gender'_group2 == 1) & yivwg2>0)(line temp_obs_wage temp_obs_wage if dgn==`gender') + graph export "$results_wi/wages_scatter_`gender'_group2.png", as(png) replace + + +************ +*histogram * +************ +*graph for both groups +if (`gender' == 0){ + + twoway (histogram temp_obs_wage if dgn==`gender' & (temp_heckman_`gender'_group1 == 1 | temp_heckman_`gender'_group2==1) & temp_obs_wage != ., /// + percent color(green) start(0) width(1)) /// + (histogram yivwg if dgn==`gender' & (temp_heckman_`gender'_group1 == 1 | temp_heckman_`gender'_group2==1) & temp_obs_wage != ., /// + percent fcolor(none) lcolor(black) start(0) width(1)), /// + legend(order(1 "observed" 2 "predicted" )) /// + subtitle("Women") /// + ytitle("percent") /// + xtitle("hourly wage, PLN") /// + xscale(range(0 100)) +} +else{ + + twoway (histogram temp_obs_wage if dgn==`gender' & (temp_heckman_`gender'_group1 == 1 | temp_heckman_`gender'_group2==1) & temp_obs_wage != ., /// + percent color(green) start(0) width(1)) /// + (histogram yivwg if dgn==`gender' & (temp_heckman_`gender'_group1 == 1 | temp_heckman_`gender'_group2==1) & temp_obs_wage != ., /// + percent fcolor(none) lcolor(black) start(0) width(1)), /// + legend(order(1 "observed" 2 "predicted" )) /// + subtitle("Men") /// + ytitle("percent") /// + xtitle("hourly wage, PLN") /// + xscale(range(0 100)) +} + +graph export "$results_wi/obs_wage_`gender'.png", as(png) replace + + + +*graph for group 1 +if (`gender' == 0){ + + twoway (histogram temp_obs_wage if dgn==`gender' & (temp_heckman_`gender'_group1 == 1) & temp_obs_wage != ., /// + percent color(green) start(0) width(1)) /// + (histogram yivwg1 if dgn==`gender' & (temp_heckman_`gender'_group1 == 1) & temp_obs_wage != ., /// + percent fcolor(none) lcolor(black) start(0) width(1)), /// + legend(order(1 "observed" 2 "predicted" )) /// + subtitle("Women") /// + ytitle("percent") /// + xtitle("hourly wage, PLN") /// + xscale(range(0 100)) +} +else{ + + twoway (histogram temp_obs_wage if dgn==`gender' & (temp_heckman_`gender'_group1 == 1) & temp_obs_wage != ., /// + percent color(green) start(0) width(1)) /// + (histogram yivwg1 if dgn==`gender' & (temp_heckman_`gender'_group1 == 1) & temp_obs_wage != ., /// + percent fcolor(none) lcolor(black) start(0) width(1)), /// + legend(order(1 "observed" 2 "predicted" )) /// + subtitle("Men") /// + ytitle("percent") /// + xtitle("hourly wage, PLN") /// + xscale(range(0 100)) +} + +graph export "$results_wi/obs_wage_`gender'_group1.png", as(png) replace + +*graph for group 2 +if (`gender' == 0){ + + twoway (histogram temp_obs_wage if dgn==`gender' & (temp_heckman_`gender'_group2==1) & temp_obs_wage != ., /// + percent color(green) start(0) width(1)) /// + (histogram yivwg2 if dgn==`gender' & (temp_heckman_`gender'_group2==1) & temp_obs_wage != ., /// + percent fcolor(none) lcolor(black) start(0) width(1)), /// + legend(order(1 "observed" 2 "predicted" )) /// + subtitle("Women") /// + ytitle("percent") /// + xtitle("hourly wage, PLN") /// + xscale(range(0 100)) +} +else{ + + twoway (histogram temp_obs_wage if dgn==`gender' & (temp_heckman_`gender'_group2==1) & temp_obs_wage != ., /// + percent color(green) start(0) width(1)) /// + (histogram yivwg2 if dgn==`gender' & (temp_heckman_`gender'_group2==1) & temp_obs_wage != ., /// + percent fcolor(none) lcolor(black) start(0) width(1)), /// + legend(order(1 "observed" 2 "predicted" )) /// + subtitle("Men") /// + ytitle("percent") /// + xtitle("hourly wage, PLN") /// + xscale(range(0 100)) +} + +graph export "$results_wi/obs_wage_`gender'_group2.png", as(png) replace +} //end of gender loop + +duplicates report //50581 obs + +sum temp_obs_wage if temp_obs_wage>0, d +sum yivwg if yivwg>0, d + +save afterheckman,replace + +*-------------------------------------------------------------------------------------------------------------------------- +*Drop individuals outside of flexible households (in "singles"' or couples' households) +*For the ease of running EUROMOD +*-------------------------------------------------------------------------------------------------------------------------- +/*We keep clean single households (exactly 1 flexible worker) and clean couple households (exactly 2 flexible workers), +and drop anything that does not match this simple household structure*/ + +use afterheckman,clear +//already problematic with lhw_f vbl +duplicates report idperson //count how many unique individuals there are +di r(unique_value) //50581 obs + +bysort idhh: egen temp_with_singles=total(temp_singles), missing //missing as 0 +replace temp_with_singles=(temp_with_singles>0) //dummy of at least one family member is "singles" + +bysort idhh: egen temp_with_couples=total(temp_couples), missing +replace temp_with_couples=(temp_with_couples>0) //dummy of at least one family member is "couples" + +count if temp_singles==1 & temp_n_ch>0 //1,029 obs + +//check whether a not flexible individual can have temp_with_couples=1 and temp_with_singles=1 at the same time +su dag if temp_with_singles==1 &temp_with_couples==1 &temp_not_flexible==1 +tab les if temp_with_singles==1 &temp_with_couples==1 &temp_not_flexible==1 //they are either pre-school or student or pensioner or disabled +*** +su temp_singles temp_couples temp_not_flexible if temp_with_singles==1 &temp_with_couples==1 //this shows singles, couples, and not flexible individuals can all live together + +count if temp_with_singles==1 &temp_with_couples==1 //8,550 obs + +//count if there are more than one flexible workers (lone parent+child aged between 16 and 18 and not student) in a "singles"' household +gen worker_count=(temp_not_flexible==0) +bysort idhh: egen number_workers_singleshh=total(worker_count) if temp_singles==1, missing +su number_workers_singles +count if number_workers_singleshh>1 & temp_singles==1 // 4,012 obs +duplicates report idhh if number_workers_singleshh>1 & temp_singles==1 + +//check there are no more than TWO flexible workers in a "COUPLES"' household +bysort idhh: egen number_workers_coupleshh=total(worker_count) if temp_couples==1, missing +su number_workers_couples +count if number_workers_coupleshh>2 & temp_couples==1 //1,006 obs +drop if number_workers_coupleshh>2 & temp_couples==1 //DP: keep them to save sample size ??? +duplicates report idperson //count how many unique individuals there are +di r(unique_value) //49575 obs + +count if number_workers_coupleshh<2 & temp_couples==1 //no such obs +drop if number_workers_coupleshh<2 & temp_couples==1 +duplicates report idperson //count how many unique individuals there are +di r(unique_value) //49575 obs + +//assert number_workers_coupleshh==2 if temp_couples==1 +assert number_workers_coupleshh>=2 if temp_couples==1 + +//dropping mixed hholds with singles and couples +count if temp_with_singles==1 &temp_with_couples==1 // 8,242 obs +drop if temp_with_singles==1 &temp_with_couples==1 //to remove "mixed hhs" (hhs who are flexible singles but live with flexible couples, +// or hhs who are flexible couples but live with flexible singles) +duplicates report idperson //count how many unique individuals there are +di r(unique_value) //41,333 obs + +*No. of hhs (lone parent+child aged between 16 and 18 and not student) +drop if number_workers_singleshh>1 & temp_singles==1 //to remove hhs with multiple ls flexible singles living together +//(2,983 observations deleted) +duplicates report idperson //count how many unique individuals there are +di r(unique_value) //38350 obs + +assert number_workers_singles==1 if temp_singles==1 + +gen temp_alt_n=(temp_with_singles==1 & temp_with_couples==0) //dummy of individuals that should have n alternatives +gen temp_alt_nsq=(temp_with_couples==1) //dummy of individuals that should have n^2 alternatives +gen temp_drop=(temp_with_singles==0 & temp_with_couples==0) //dummy of individuals that can be dropped from EUROMOD input data +//because they are neither singles nor couples and do not live with singles or couples +assert temp_not_flexible==1 if temp_drop==1 //check that all individuals who will be dropped are not flexible +assert temp_alt_n+temp_alt_nsq+temp_drop==1 + +//check hours of work after all the drops +fre temp_lhw_dobs_0 if dgn==0 & temp_couples ==1 //24.3% with zero hours ==> 23.3% +fre temp_lhw_dobs_1 if dgn==1 & temp_couples ==1 //8.6% with zero hours ==> 6.9% + +fre temp_lhw_dobs_0 if dgn==0 & temp_singles_indep==1 //33.9% with zero hours ==> 29.7% +fre temp_lhw_dobs_1 if dgn==1 & temp_singles_indep==1 //24.3% with zero hours ==> 21.3% + +fre temp_lhw_dobs_0 if dgn==0 & temp_singles_dep==1 //48.2% with zero hours ==> 47.6% +fre temp_lhw_dobs_1 if dgn==1 & temp_singles_dep==1 //26.5% with zero hours ==> 27.2% + + +*======================================================================= +* Labour supply alternatives +*======================================================================= +tab les if temp_drop==1 +tab dag if temp_drop==1 &(les==2|les==3) + +drop if temp_drop==1 //to reduce the burden of EUROMOD +duplicates report idperson //count how many unique individuals there are +//(8,810 observations deleted) 29540 obs remain + +* create columns with imputed alternatives (same for everyone who is labour supply flexible) +foreach gender in 0 1{ +local i = 0 +levelsof temp_lhw_dobs_`gender', local(levels) +foreach l in `r(levels)' { + gen byte temp_lhw_dobs_`gender'_`i' = `l' if temp_not_flexible==0 + local i = `i' + 1 +} //loop end of ls alternatives `i' +} //loop end of gender `gender' +sum temp_lhw_dobs_* + + +/* +forvalues i = 1 (1) $n_workchoices{ + assert lhw != . + replace temp_bracket = `i' if lhw > $min_hours_`i' +} +*/ + +* choice set: generation of $n_choices^2 columns +// first index refers to male choice, second index refers to female choice +// note: couples (both partners flexible) have access to all $n_choices^2 options, +// note: Although "singles" have access only to $n_choices options, I replicate these $n_choices across all choices of their partners. +// note: not flexible individuals' all options =0 hrs +// Due to the way to construct fake id* to cheat EUROMOD, the treatment to "singles" and not flexible individuals is only for the purpose +// of linking with flexible people in the same hh to provide info for EUROMOD. +forvalues m=0/$n_workchoices { + forvalues f=0/$n_workchoices { + + capture drop lhw_`m'`f' + gen byte lhw_`m'`f' = . + replace lhw_`m'`f'=0 if temp_not_flexible==1 //both genders of not flexible individuals + // males + replace lhw_`m'`f' = temp_lhw_dobs_1_`m' if dgn == 1 & (temp_couples==1 |temp_singles==1) //male partner in flexible couples and male individuals in "singles" + + // females + replace lhw_`m'`f' = temp_lhw_dobs_0_`f' if dgn == 0 & (temp_couples==1 |temp_singles==1) //female partner in flexible couples and female individuals in "singles" + } +} + +* choice conversion +// for flexible couples, flag for choice_`m'`f' is switched on only when the male partner chooses `m' and the female partner chooses `f' +// for second type of "singles", the inflexible partner always chooses 1st bracket (ie. 0 hours) +// for first type of "singles" (without a partner), we assume that their virtual partner chooses 1st bracket (ie. 0 hours). +// first index refers to male choice, second index refers to female choice + +add_partner_variables "temp_bracket_0 temp_bracket_1 dgn" + replace partner_temp_bracket_0 = 0 if idpartner>0 &partner_dgn==0 &(temp_p_student==1|temp_p_sick_dis==1|temp_p_workage==0) //second type of "singles"' partner must not work + replace partner_temp_bracket_1 = 0 if idpartner>0 &partner_dgn==1 &(temp_p_student==1|temp_p_sick_dis==1|temp_p_workage==0) //second type of "singles"' partner must not work + + +forvalues m=0/$n_workchoices { + forvalues f=0/$n_workchoices { + gen byte temp_choicehh_`m'`f' = . + // males + replace temp_choicehh_`m'`f' = (temp_bracket_1 == `m' & partner_temp_bracket_0 == `f') if dgn == 1 & temp_couples==1 //male partner in flexible couples + replace temp_choicehh_`m'`f' = (temp_bracket_1 == `m') if dgn == 1 & temp_singles==1 & `f' == 0 //male "singles" + // females + replace temp_choicehh_`m'`f' = (temp_bracket_0 == `f' & partner_temp_bracket_1 == `m') if dgn == 0 & temp_couples==1 //female partner in flexible couples + replace temp_choicehh_`m'`f' = (temp_bracket_0 == `f') if dgn == 0 & temp_singles==1 & `m' == 0 //female "singles" + } +} + + +drop partner_temp_bracket* +*------------------------------------------------------------ +* Earnings +*------------------------------------------------------------ +cap drop yem yse +gen yem = yempj + yemtj +gen yse = yseag + ysebs +gen temp_em=(yem>yse |(yem==yse & yem!=0)) //assign income to be employed income or self-employed income depending on whether yem>=yse for workers +gen temp_se=(yse>yem) //assign income to be employed income or self-employed income depending on whether yem>yse for workers + +assert temp_em==(1-temp_se) if yem!=0|yse!=0 //checking that non-zero hours working regimes either belong to temp_em or temp_se category +gen temp_nonworker=(yem==0 & yse==0) +assert (temp_em+temp_se+temp_nonworker==1) //checking that all regimes belong to one of the following: temp_em, temp_se, temp_nonworker +//for workers' all states, assume all income are employed income or self-employed income depending which is their major income source in their actual state + +forvalues m=0/$n_workchoices { + forvalues f=0/$n_workchoices { +gen yem_`m'`f' = . +gen yse_`m'`f' = . + +replace yem_`m'`f'=yivwg*lhw_`m'`f'*4.3 if temp_em==1 +replace yse_`m'`f'=0 if temp_em==1 + +replace yse_`m'`f'=yivwg*lhw_`m'`f'*4.3 if temp_se==1 +replace yem_`m'`f'=0 if temp_se==1 + +// for non-workers' counterfacual states, assume all income are employed income +replace yem_`m'`f'=yivwg*lhw_`m'`f'*4.3 if temp_nonworker==1 +replace yse_`m'`f'=0 if temp_nonworker==1 + + } +} + +gen temp_yem=yem +gen temp_yse=yse +drop yem yse +*NOTE: for both the actual and counter-factural states, yem and yse are computed using wage*discretised hours of work. This now holds automatically because wage is generated as income/discritized hours + + +*----------------------------------------------------------------------------------- +* Generation of new identifiers for each LS alternative +*----------------------------------------------------------------------------------- +/* +foreach var in idhh idperson idpartner idfather idmother { + capture drop `var'* +} +*/ +forvalues m=0/$n_workchoices { + forvalues f=0/$n_workchoices { + foreach var in idhh idperson idpartner idfather idmother { + gen double `var'_`m'`f' = `var' * 100 + `m'*10 + `f' //fake id to cheat EUROMOD + replace `var'_`m'`f' = 0 if `var' == 0 + } + } +} + +*check idperson identifies persons uniquely +duplicates r idperson +gen double temp_idorigperson2=idperson //save original id. idorigperson (within hh id) already existed and not the same as idperson +gen temp_idorigpartner=idpartner +gen temp_idorighh=idhh +gen temp_idorigmother=idmother +gen temp_idorigfather=idfather +drop idperson idpartner idhh idmother idfather + +format temp_id* %15.0g +duplicates r temp_idorigperson2 +di r(unique_value) //8045 obs +/* +foreach var of varlist idhh idperson idpartner idfather idmother lhw yem yse { + quietly rename `var' obs_`var' +} + +*/ +preserve +drop idhh_* idperson_* idpartner_* idfather_* idmother_* lhw_* yem_* yse_* temp_choicehh_* +save full_info,replace +restore +save beforeReshape.dta,replace + + +*======================================================================= +* Reshaping data +*======================================================================= + +use beforeReshape.dta, clear +duplicates report temp_idorigperson2 //count how many unique individuals there are +di r(unique_value) //29540 obs + +keep temp_idorigperson2 idhh_* idperson_* idpartner_* idfather_* idmother_* lhw_* yem_* yse_* temp_choicehh_* + +local reshapevbles = "idhh_ idperson_ idpartner_ idfather_ idmother_ lhw_ yem_ yse_ temp_choicehh_" +reshape long `reshapevbles', i(temp_idorigperson2) j(temp_option) string + + +format id* %15.0g + foreach var in idhh idperson idpartner idfather idmother lhw yem yse temp_choicehh { + rename `var'_ `var' +} +duplicates report idperson // no duplicates +duplicates report idhh + +merge m:1 temp_idorigperson2 using full_info +assert _merge==3 +drop _merge +gen ind_option = substr(temp_option,1,1) if dgn==1 //alternative bracket for individual male +replace ind_option = substr(temp_option,2,1) if dgn==0 //alternative bracket for individual female +destring ind_option, force replace +gen temp_choice=(ind_option==temp_bracket_0) if dgn==0 //dummy for female individual choice +replace temp_choice=(ind_option==temp_bracket_1) if dgn==1 //dummy for male individual choice + +drop ind_option + +destring temp_option, force gen (temp_seq) +//check data structure +gsort temp_idorigperson2 temp_seq //Place observations in ascending order of temp_seq within ascending order of original person id +bysort temp_idorigperson2:egen temp_seq2=seq() //give each working regime a label from 1 to $n_choice^2 +replace lhw=0 if temp_not_flexible==1 //not flexible persons should have zero hours of work + +bysort temp_idorigperson2: egen double mean_choicehh=mean(temp_choicehh) //compute the mean of flag of hh choice for the same individual +assert mean_choicehh==1/($n_choices)^2 if temp_couples==1 //for an individual in a flexible couple, 1 option is chosen from ($n_choices)^2 options +assert mean_choicehh==1/($n_choices) if temp_singles==1 //for an individual in "singles", 1 option is chosen from $n_choices options +assert lhw!=. & yem!=. & yse!=. if temp_singles==1|temp_couples==1 //make sure lhw, yse, yse are not missing for sample to be included in labour supply estimation +drop mean_choicehh + +assert temp_choicehh!=. if temp_couples==1 +assert temp_choicehh==. if temp_not_flexible==1 +//note: for each individual in "singles", $n_choices out of $n_choices^2 temp_choicehh are non-missing + +gen count=1 +bysort temp_idorigperson2: egen sum_option=total(count) //compute the sum of options +assert sum_option==$n_choices^2 //up to this point, every individual has $n_choices^2 alternatives +drop count sum_option + + +//update in v8 +drop if temp_choicehh==. & temp_singles==1 //drop invalid rows for singles +duplicates report temp_idorigperson2 //count how many unique individuals there are +di r(unique_value) + + +bysort idhh: egen temp_with_singles2=total(temp_singles) //the previously generated temp_with_singles may not be useful because up to this point some singles are dropped already +drop if temp_with_singles2==0 & temp_with_couples==0 & temp_not_flexible==1 //delete not flexible people with no singles or couples to attach to +duplicates report temp_idorigperson2 //count how many unique individuals there are +di r(unique_value) //28235 obs + +gen count=1 +bysort temp_idorigperson2: egen sum_option=total(count) //compute the sum of options + +assert sum_option==$n_choices^2 if temp_alt_nsq==1 //yes +assert sum_option==$n_choices if temp_alt_n==1 +su temp_alt_nsq temp_with_singles temp_with_couples if temp_not_flexible==1 +drop count sum_option +//check again +assert temp_choicehh!=. if temp_couples==1 +assert temp_choicehh!=. if temp_singles==1 //this is new because now singles only have $n_choices kept, solved-contradiction: all aged 16,17,temp_alt_nsq==1, having 12 choices +assert temp_choicehh==. if temp_not_flexible==1 + +*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +* Correct values for benefits 1/2 +*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// @@@ BENEFITS COUNTERFACTUAL ALLOCATION: ASSUMPTION #2(A) @@@ +/*SIMULATED BENEFITS: +Do not worry about them as EUROMOD calculates +the right amount in all choices, given other variables are set correctly. + +*the code below is not relevant for PL +*Notes about bunct_s (unemployment benefit (JSA)): PARTLY SIMULATED, i.e. IT IS SIMULATED BUT THE SIMULATION TAKES SOME VALUES FROM THE DATA. YOU CAN CONSIDER THAT AS "SIMULATED" +//check which variables are used to simulate and manipulate those variables rather than the bunct_s per se, to make bunct_s=0: +preserve +keep id* les bunct +rename les temp_les +rename bunct temp_bunct +save les_bunct,replace //store the original les and bunct for future use if needed +restore +replace les=5 if temp_singles==1|temp_couples==1 +replace bunct=0 if temp_singles==1|temp_couples==1 +*/ + +// @@@ BENEFITS COUNTERFACTUAL ALLOCATION: ASSUMPTION #2(B1) @@@ +/*BENEFITS NOT SIMULATED, COMPATIBLE WITH A WORKING CONDITION BUT DEPEND ON YEM\LHW: +Set them to zero (Otherwise they are positive only in the observed choice and not modelled in the other choices, +and this creates a bias in the estimates of the utility function).*/ +/*Italy +drop if (bmals>0|bmase>0)& lhw==0 & (temp_singles==1|temp_couples==1) // bmals:Maternity payments (lump sum); bmase:Maternity payments (only self emp). +duplicates report temp_idorigperson2 //count how many unique individuals there are +di r(unique_value) + +replace bsa00=0 if temp_singles==1|temp_couples==1 //Social assistance(Minimum Insertion Income ) +replace bsa01=0 if temp_singles==1|temp_couples==1 //Social assistance (Basic Needs Debit Card ) +*/ +/*UK +replace bot=0 if temp_singles==1|temp_couples==1 //other benefits +drop if (bmaer>0|bmana>0)& lhw==0 & (temp_singles==1|temp_couples==1) // bmaer: Statutory maternity pay; bmana: Maternity Allowance (Only 40 obs are dropped from the original whole sample) +*Notes about maternity leave: +// Assume that one who receives at least one of the these benefits (Statutory maternity pay (bmaer) or Maternity Allowance (bmana)) +//as being on maternity leave but think of them as “working”. +*/ + +/*DP: No such benefits in HU (materinity ones are simulated)*/ + +/*PL: +fre bcc //Supplement to the family allowance for parents who take unpaid childcare leave to care for a young child. +fre bchunlp //benefit for unemployed lone parents +fre bma //Maternity allowance +fre ysv //severance payment +*/ +foreach var in bcc bchunlp bma ysv { +replace `var'=0 if temp_singles==1|temp_couples==1 +} +/*(488 real changes made) +(0 real changes made) +(4,236 real changes made) +(20 real changes made) +*/ + +// @@@ BENEFITS COUNTERFACTUAL ALLOCATION: ASSUMPTION #2(B2) @@@ +/*BENEFITS NOT SIMULATED, NOT COMPATIBLE WITH A WORKING CONDITION AND DO NOT DEPEND ON YEM\LHW: +Set them equal to the amount in the observed choice.*/ +/* HU: +bed: education related income (oktatással kapcsolatos támogatás) +bho: housing benefit +botre: other regular benefits - N/A in the dataset +bfaot: other family benefits (includes maternity allowance, child care fee and nursing fee) - N/A in the dataset +*/ + +/*PL: +fre bsaot //neither permanent nor temporary social assistance ==> granted once or occasionally for specific urgent needs +fre bed //scholarships +*/ +cap drop mean_* +foreach var in bed bsaot { +bysort temp_idorigperson2: egen mean_`var'=mean(`var') +//assert `var'==mean_`var' //make sure `var' is equal to the amount in the observed choice +assert abs(`var' - mean_`var') <= 0.1 +drop mean_`var' +} + +// @@@ BENEFITS COUNTERFACTUAL ALLOCATION: ASSUMPTION #2(B3) @@@ +/* +BENEFITS NOT SIMULATED, NOT COMPATIBLE WITH A WORKING CONDITION AND AN INDIVIDUAL RECEIVES THEM IN THE OBSERVED CHOICE (E.G. A DISABILITY BENEFIT): +Exclude this individual from the sample used for labour supply estimates because it means that, in the observed choice, the individual +has some charateristics incompatible with a working condition +*/ +/* Italy +drop if bunct01>0 & (temp_singles==1|temp_couples==1) //Unemployment benefit (Cassa Integrazione Guadagni) +drop if bunct02>0 & (temp_singles==1|temp_couples==1) //Unemployment benefit (Indennita' di Disoccupazione - Mobilita') +drop if bunst>0 & (temp_singles==1|temp_couples==1) //Unemployment benefit s.t. training +drop if yunsv>0 & (temp_singles==1|temp_couples==1) //Severance pay (Liquidazioni da lavoro - TFR) +duplicates report temp_idorigperson2 //count how many unique individuals there are +di r(unique_value) +*/ +/*UK +drop if bedes>0 & (temp_singles==1|temp_couples==1) //Student payments +drop if bedsl>0 & (temp_singles==1|temp_couples==1) //Student Loan +drop if bdioa>0 & (temp_singles==1|temp_couples==1) //Attendance allowance +drop if bdisc>0 & (temp_singles==1|temp_couples==1) //Disability living allowance +drop if bdimb>0 & (temp_singles==1|temp_couples==1) //Disability living (mobility) allowance +drop if bdiscwa>0 & (temp_singles==1|temp_couples==1) //PIP living allowance +drop if bdimbwa>0 & (temp_singles==1|temp_couples==1) // PIP mobility + +drop if bdict0117>0 & (temp_singles==1|temp_couples==1) //Incapacity Benefit 2017 +drop if bdict0118>0 & (temp_singles==1|temp_couples==1) //Incapacity Benefit 2018 +drop if bdict0217>0 & (temp_singles==1|temp_couples==1) //Contributory ESA 2017 +drop if bdict0218>0 & (temp_singles==1|temp_couples==1) //Contributory ESA 2018 + +drop if bdiwi>0 & (temp_singles==1|temp_couples==1) //Industrial injuries pension +drop if bcrdi>0 & (temp_singles==1|temp_couples==1) //Invalid care allowance +drop if bdisv>0 & (temp_singles==1|temp_couples==1) //Severe disablement allowance +drop if bhlwk>0 & (temp_singles==1|temp_couples==1) //Statutory sick pay +drop if buntr>0 & (temp_singles==1|temp_couples==1) //Training allowance +*/ + +/*HU: only pdi - disability pension - could be classified as such +drop if pdi>0 & (temp_singles==1|temp_couples==1) */ + +/*PL: all pensions are compatible with working condition but their earnings are (strictly) limited and may affect their pension. Not sure how to account for that because they are not simulated. +==> opted for removing people on disability pensions completely +fre pdi00 //Disability pension (agricultural and non-agricultural) +fre pdinw //Social pension +fre poa00 //Retirement pension (agricultural and non-agricultural) +fre poafr //Farmer's structural pension +fre poaot //pension : old age : other +fre psu00 //Survivors pension (agricultural and non-agricultural) +fre pyr //Pre-retirement allowance and benefit +*/ +drop if pdi00>0 | pdinw>0 & (temp_singles==1|temp_couples==1) //(5,896 observations deleted) + +///////////////////////////////////////////////////////////// +//Now after benefit correction, check data structure again // +///////////////////////////////////////////////////////////// +gen d=1 +bysort temp_idorigperson2: egen count=total(d) +su count +drop if count!=($n_choices)^2 &temp_alt_nsq==1 +duplicates report temp_idorigperson2 //count how many unique individuals there are +di r(unique_value) + +drop if count!=($n_choices) &temp_alt_n==1 +duplicates report temp_idorigperson2 //count how many unique individuals there are +di r(unique_value) + +drop d count +gsort temp_idorigperson2 temp_seq //Place observations in ascending order of temp_seq within ascending order of original person id +assert lhw==0 if temp_not_flexible==1 //not flexible persons should have zero hours of work + +bysort temp_idorigperson2: egen double mean_choicehh=mean(temp_choicehh) //compute the mean of flag of hh choice for the same individual +assert mean_choicehh==1/($n_choices)^2 if temp_couples==1 //for an individual in a flexible couple, 1 option is chosen from ($n_choices)^2 options +assert mean_choicehh==1/($n_choices) if temp_singles==1 //for an individual in "singles", 1 option is chosen from $n_choices options +assert lhw!=. & yem!=. & yse!=. if temp_singles==1|temp_couples==1 //make sure lhw, yse, yse are not missing for sample to be included in labour supply estimation + +drop mean_choicehh + + +/* +//@@@ tax compliance assumption #1@@@ +//assume full tax compliance, set yseev and ysenr to 0 and hence set TCA off in EUROMOD +//NOTE: an additional step to finish this assumption is to set TCA off which means adding -extSwitch "TCA=off" in the command to run EUROMOD later +// Without this additional step, EUROMOD will still keep the defualt setting, i.e. TCA is on. +//replace yseev=0 +//replace ysenr=0 + +//@@@ tax compliance assumption #2@@@ +//assume no full tax compliance, fill in yseev, ysenr +//replace yseev=0.5*yse //50% SE income reported to tax authority under no full tax compliance +//replace ysenr=0.5*yse //50% SE income not reported to tax authority under no full tax compliance +gen ratio_yseev=yseev/(yseev+ysenr) //this is how the ratio of total se income reported to tax authority (assume this to be the same in every alternative for the same individual) +gen ratio_ysenr=ysenr/(yseev+ysenr) //this is how the ratio of total se income not reported to tax authority (assume this to be the same in every alternative for the same individual) +replace yseev=ratio_yseev*yse if yseev!=0|ysenr!=0 +replace ysenr=ratio_ysenr*yse if yseev!=0|ysenr!=0 +assert yseev!=. +assert ysenr!=. +*/ + +*------------------------------------------------------------ +* Store information not for EUROMOD for later use +*------------------------------------------------------------ +preserve +keep id* temp* +save temp_file.dta, replace +restore +duplicates report temp_idorigperson2 //count how many unique individuals there are +di r(unique_value) //27463 +assert temp_singles_indep+temp_singles_dep+temp_couples+temp_not_flexible==1 +count if temp_singles_indep==1&temp_choicehh==1 //3,192 +count if temp_singles_dep==1 &temp_choicehh==1 //1,457 +count if temp_couples==1 &temp_choicehh==1 //11,388 +count if temp_not_flexible==1&temp_choicehh==1 //0 + +/*VERY IMPORTANT: PL model does not use yem and yse as other models do. PL splits these income by type because different tax regimes are applied to different types of earnings +This needs to be chnaged before data enters the model otherwise there will be no diferences in earnings by alternatives */ +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +foreach var in yempj yemtj yseag ysebs { +gen temp_`var'= `var' +} //save original values + +cap drop yempj yemtj +gen yempj = 0 +replace yempj = yem if temp_yempj>0 & temp_yemtj==0 +gen yemtj = 0 +replace yemtj = yem if temp_yempj==0 & temp_yemtj>0 + +cap drop yseag ysebs +gen yseag = 0 +replace yseag = yse if temp_yseag>0 & temp_ysebs==0 +gen ysebs = 0 +replace ysebs = yse if temp_yseag==0 & temp_ysebs>0 +*end of correction +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +save individuals.dta,replace + +*======================================================================= +* create EUROMOD input data +*======================================================================= +*---------------------------------------------------------------------------------------------------- +* singles_wage1.dta as input data(Predicted wage for everyone), but not in the EM input folder yet +*----------------------------------------------------------------------------------------------------- +use individuals,clear +drop temp* //This is because as per EUROMOD conventions, some variables should not appear in the input database. +sort idhh idperson +drop number* partner_dgn _est* //ratio* + +save individuals_wage1.dta, replace + +*------------------------------------------------------------------------------------------------------------- +* singles_wage2.dta as input data(Predicted wage for non-workers only), but not in the EM input folder yet +*------------------------------------------------------------------------------------------------------------- +use individuals,clear +drop number* partner_dgn _est* //ratio* + +*************************************************** +* // @@@ WAGE IMPUTATION METHOD #wage2@@@ +* make predicted wage=yivwg only for non-workers +*(before this yivwg=predicted wage for everyone) +**************************************************** +replace yivwg=temp_obs_wage if temp_em==1|temp_se==1 //for workers used for the Heckman estimation, wages=actual wages +/* +//for workers' all states, assume all income are employed income or self-employed income depending which is their major income source in their actual state +replace yem=yivwg*lhw*4.3 if temp_em==1 +replace yse=0 if temp_em==1 + +replace yse=yivwg*lhw*4.3 if temp_se==1 +replace yem=0 if temp_se==1 + +// for non-workers' counterfacual states, assume all income are employed income +replace yem=yivwg*lhw*4.3 if temp_nonworker==1 &temp_choice==0 +*/ + +/*VERY IMPORTANT: here's an additional correction of earnings specific for PL model */ +///////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//for workers' all states, assume all income are employed income or self-employed income depending which is their major income source in their actual state +replace yempj=yivwg*lhw*4.3 if temp_em==1 & yempj>0 +replace yemtj=yivwg*lhw*4.3 if temp_em==1 & yemtj>0 +replace yseag=0 if temp_em==1 +replace ysebs=0 if temp_em==1 + +replace yseag=yivwg*lhw*4.3 if temp_se==1 & yseag>0 +replace ysebs=yivwg*lhw*4.3 if temp_se==1 & ysebs>0 +replace yempj=0 if temp_se==1 +replace yemtj=0 if temp_se==1 + +// for non-workers' counterfacual states, assume all income are employed income +replace yempj=yivwg*lhw*4.3 if temp_nonworker==1 &temp_choice==0 +replace yemtj=yivwg*lhw*4.3 if temp_nonworker==1 &temp_choice==0 +*end of correction +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +drop temp* //This is because as per EUROMOD conventions, some variables should not appear in the input database. +sort idhh idperson + +save individuals_wage2.dta, replace + +*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +* Correct values for benefits 2/2 +*To be precise, no actual correction is done here, the point is to replicate benefits to +*all alternatives to make a data set called special_partners.dta, +*and append this to the "singles" to make EUROMOD input data +// @@@ BENEFITS COUNTERFACTUAL ALLOCATION: ASSUMPTION #1 @@@ +*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +*loop through wage1, wage2:export as em input file, then run EM, then save output in the result folder for labour supply estimation, +*named "individuals_output_wage`i'" + +foreach i in 1 2{ +//local i=2 //only do for wage1 +use individuals_wage`i',clear +export delimited "$em_input\$file_input.txt", replace nolabel delim(tab) //create input data for EUROMOD +************************************************************ +* Run EUROMOD with Stata +************************************************************ +//note that input data for PL is in national currency - but we want output is euros - this needs to be manually changed in model settings. +version 13 +* Call EUROMOD + +capture erase "${em_output}\$file_output.txt" //erase previous output file, this is done in case EUROMOD call from Stata fails, to be sure we are not opening an early run of the model + //2018 earnings (2019 data) and 2018 system +shell "${em_exe}" -emPath "${em_models}" -sys PL_2018 -data PL_2019_b3 -forceOutputInEuro //call EUROMOD 1:Program to call 2: path for folder 3: system name 4: dataset to use + +*import EUROMOD RUN + +import delimited "${em_output}\$file_output.txt", clear //import data from txt file in output folder + +/*drop individuals causing errors +drop if idperson==1000200 //parts of yse do not sum up 0 <> 9666.6659 +drop if idpesron==1000201 //parts of yse do not sum up 0 <> 9666.6659 +drop if idperson==1000202 //parts of yse do not sum up 0 <> 9666.6659 +drop if idperson==7925000120 //parts of yse do not sum up 1705.46648 <> 2131.8331 +drop if idperson==7925000121 //parts of yse do not sum up 1705.46648 <> 2131.8331 +*/ + +save individuals_output_wage`i',replace + +} + +log close diff --git a/input_processing/labour_supply/do-files/std singles and couples data preparation/2a-singles sample-std model.do b/input_processing/labour_supply/do-files/std singles and couples data preparation/2a-singles sample-std model.do new file mode 100644 index 0000000..27cf578 --- /dev/null +++ b/input_processing/labour_supply/do-files/std singles and couples data preparation/2a-singles sample-std model.do @@ -0,0 +1,238 @@ +************************************************************************** +* Poland EM data (PL_2019_b3.txt data) +* Labour supply estimation-get sample for single and generate the vbls needed for ls (std singles) +************************************************************************* + + +global file_log="${log}/singles_sample-std model" +global n_choices = 4 // 4 choices: no work, plus 3 hours brackets. + + +cd "$local_data" + +capture log close +log using "$file_log", replace +pwd +clear all +set seed 1 //same seed gives same results + +*version 15 + +//update 1/2/2021: at the end of the do file, separate the sample into two subsamples: singles_indep and singles_dep +*loop through wage1, wage2: hours of work estimation for each gender (triple loop) + +//loop over wage1, wage2 +foreach i in 1 2{ //loop begin for wage imputation method +use "individuals_output_wage`i'",clear +label var lhw "weekly hours worked" + +//assert bunct_s==0 //N/A for HU: making sure unemployment benefit (JSA): bunct_s=0 for every alternatives for everyone +gen sim_flag=0 //needed because this should contain the same variables as in dataset to be appended + +merge m:1 idperson using "temp_file.dta" //add additional information +assert _merge==3 +drop _merge +duplicates report temp_idorigperson2 if temp_singles==1 //count how many unique individuals there are +di r(unique_value) + +gen d40=(dag>=40) + +gen d45=(dag>=45) + +//dummy of living with elderly (aged>=50), including themselves +gen d50=(dag>=50) +bysort temp_idorighh:egen d_with_elderly50=total(d50) //up to here d_with_elderly60=the no. of elderly in hh* $n_choices +replace d_with_elderly50=(d_with_elderly50>0) +label variable d_with_elderly50 "1(living with people aged 50+)" + +//dummy of living with elderly (aged>=55), including themselves +gen d55=(dag>=55) +bysort temp_idorighh:egen d_with_elderly55=total(d55) //up to here d_with_elderly60=the no. of elderly in hh* $n_choices +replace d_with_elderly55=(d_with_elderly55>0) +label variable d_with_elderly55 "1(living with people aged 55+)" + +//dummy of living with elderly (aged>=60), including themselves +gen d60=(dag>=60) +bysort temp_idorighh:egen d_with_elderly60=total(d60) //up to here d_with_elderly60=the no. of elderly in hh* $n_choices +replace d_with_elderly60=(d_with_elderly60>0) +label variable d_with_elderly60 "1(living with people aged 60+)" + +//dummy of living with elderly (aged>=65), including themselves +gen d65=(dag>=65) +bysort temp_idorighh:egen d_with_elderly65=total(d65) //up to here d_with_elderly60=the no. of elderly in hh* $n_choices +replace d_with_elderly65=(d_with_elderly65>0) +label variable d_with_elderly65 "1(living with people aged 65+)" + +//dummy of living with elderly (aged>=70), including themselves +gen d70=(dag>=70) +bysort temp_idorighh:egen d_with_elderly70=total(d70) //up to here d_with_elderly60=the no. of elderly in hh* $n_choices +replace d_with_elderly70=(d_with_elderly70>0) +label variable d_with_elderly70 "1(living with people aged 70+)" + +//dummy of living with elderly (aged>=75), including themselves +gen d75=(dag>=75) +bysort temp_idorighh:egen d_with_elderly75=total(d75) //up to here d_with_elderly60=the no. of elderly in hh* $n_choices +replace d_with_elderly75=(d_with_elderly75>0) +label variable d_with_elderly75 "1(living with people aged 75+)" + +label variable les "economic status" //les=4: pensioner +gen d_se=(les==2) //dummy of being self-employed +label variable d_se "1(self-employed)" + +******** + +bysort idhh: egen hhcon=sum(ils_dispy) //hh income, should be done before keeping only the target sample +//assert hhcon==. if sim_flag==1 +label variable hhcon "income" +keep if temp_singles==1 &temp_choicehh!=. //target sample: "singles", and keep only $n_choices rows for each individual + +//check data structure +bysort temp_idorigperson2: egen double mean_choicehh=mean(temp_choicehh) //compute the mean of flag of hh choice for the same individual +assert mean_choicehh==1/($n_choices) if temp_singles==1 //for an individual in "singles", 1 option is chosen from $n_choices options + +assert lhw!=. & yem!=. & yse!=. if temp_singles==1 //make sure lhw, yse, yse are not missing for sample to be included in labour supply estimation + +//generation of vbls +//house ownership +gen d_owner=(amrtn==1|amrtn==2) +label variable d_owner "house owner (on mortgage or outright)" + +gen d_owner_out=(amrtn==2) //own outright +label variable d_owner_out "house owner (outright)" + +gen d_owner_mort=(amrtn==1) //own on mortgage +label variable d_owner_mort "house owner (on mortgage)" + +gen d_renter_social=(amrtn==5) //own on mortgage +label variable d_renter_social "house renter (social rented)" + +*********************** +gen leisure=24*7-lhw +replace leisure=0 if leisure<0 //define leisure for utility function +label variable leisure "leisure" + +//participation dummy +gen fixed_cost=(lhw>0) //define a fixed-cost of work (dummy) +label variable fixed_cost "fixed cost for labour" + +//gen part-time fixed cost +gen part_fixed_cost=(lhw<40 &lhw>0) //in HU full-time work is 40 hours per week +label variable part_fixed_cost "fixed cost for part-time work" + +//gen full-time fixed cost +gen full_fixed_cost=(lhw>=40) +label variable full_fixed_cost "fixed cost for full-time work" + +//gen interaction of fixed cost with gender +gen fixc_dgn=fixed_cost*dgn +lab var fixc_dgn "fixed cost for labour$\times$1(male)" + +//social norm? +gen hrs_40=(lhw==40) +label var hrs_40 "1(weekly working hours=40)" + +gen hrs_40plus=(lhw>=40) +label var hrs_40plus "1(weekly working hours>=40)" + +//gen interaction of 40 hours dummy with gender +gen hrs_40_dgn=hrs_40*dgn +lab var hrs_40_dgn "1(weekly working hours=40)\times$1(male)" + +gen hrs_40plus_dgn=hrs_40plus*dgn +lab var hrs_40plus_dgn "1(weekly working hours>=40)\times$1(male)" + +//experience variable +//gen liwwh_0 = (liwwh==0) //zero experience +gen liwwh_1 = (liwwh>=0 & liwwh<1) //less than a year experience +gen liwwh_2 = (liwwh>=1 & liwwh<5) //1 to 5 years experience +gen liwwh_3 = (liwwh>=5) //5+ years experience +//lab var liwwh_0 "no experience" +lab var liwwh_1 "0-1 years (new entrants)" +lab var liwwh_2 "1-5 years (some experience)" +lab var liwwh_3 "5+ years (highly experienced)" + +gen ln_liwwh = ln(liwwh + 1) + +foreach var in liwwh { + gen `var'2=(`var'^2) + label variable `var'2 "`var'^2" + } + +* Generation of variables squared + foreach var in leisure hhcon { + gen `var'2=(`var'^2) + label variable `var'2 "`var'^2" + } + +//rescale age and age^2 +gen age_100=dag/100 +label variable age_100 "age/100" + +gen age2_10000= temp_age2/10000 +label variable age2_10000 "age^2/10000" + +//rescale hhcon and hhcon^2 +gen hhcon_100=hhcon/100 +label variable hhcon_100 "income/100" + +gen hhcon2_10000= hhcon2/10000 +label variable hhcon2_10000 "income^2/10000" + +*generation of interactions with household income +global incomex "age_100 age2_10000 temp_n_ch temp_d_ch2 d_owner_out d_owner_mort d_renter_social temp_hhsize temp_dhe_1 temp_dhe_2 temp_dhe_3 temp_dhe_4 temp_dhe_5" +foreach x of varlist $incomex{ +gen hhcon_100_`x'=hhcon_100*`x' +local varlabel : var label `x' +label variable hhcon_100_`x' "income/100#`varlabel'" +} + +/*combining regions +//North West + North East= North +gen temp_north=temp_region1+temp_region2 +lab var temp_north "North" +//South + Islands= South +gen temp_south_islands=temp_region4+temp_region5 +lab var temp_south_islands "South and Islands" +*/ + +*generation of interactions with fixed cost for labour +global fixedcostx "temp_n_ch temp_d_ch2 temp_p_sick_dis temp_p_student d_owner_out d_owner_mort d_renter_social temp_p_pensioner temp_d_deh_L temp_d_deh_M temp_d_deh_H d60 d65 d70 temp_region1 temp_region2 temp_region3 temp_region4 temp_region5 temp_region6 temp_region7 temp_dhe_1 temp_dhe_2 temp_dhe_3 temp_dhe_4 temp_dhe_5" +foreach x of varlist $fixedcostx{ +gen fixc_`x'=fixed_cost*`x' +local varlabel : var label `x' +label variable fixc_`x' "fixed cost for labour#`varlabel'" +} + +*generation of interactions with leisure +global lx "hhcon_100 age_100 age2_10000 temp_n_ch temp_d_ch* temp_d_deh_L temp_d_deh_M temp_d_deh_H temp_region1 temp_region2 temp_region3 temp_region4 temp_region5 temp_region6 temp_region7 d_owner_out d_owner_mort d_renter_social temp_hhsize temp_dhe_1 temp_dhe_2 temp_dhe_3 temp_dhe_4 temp_dhe_5" +foreach x of varlist $lx{ +gen lei_`x'=leisure*`x' +local varlabel : var label `x' +label variable lei_`x' "leisure#`varlabel'" +} + +*estimate labour supply model and compute predicted choices +// LS model of choices (0,20,40,50). By default assumes quadratic utility. verbose shows more detail + +bysort temp_idorigperson2: egen min_hhcon=min(hhcon) +drop if min_hhcon<=0 //consumption is not allowed to be 0 or negative for lslogit + +duplicates report temp_idorigperson2 if temp_singles==1 //count how many unique individuals there are +di r(unique_value) + + +//subsample: singles_indep +preserve +keep if temp_singles_indep==1 +save singles_indep_wage`i',replace +restore +//subsample: singles_indep +preserve +keep if temp_singles_dep==1 +save singles_dep_wage`i',replace +restore + +save singles_wage`i',replace //still save this, as will be used in EM sample (1.1wage) +} //loop end for wage imputation method + +log close diff --git a/input_processing/labour_supply/do-files/std singles and couples data preparation/2b-couples sample-std model.do b/input_processing/labour_supply/do-files/std singles and couples data preparation/2b-couples sample-std model.do new file mode 100644 index 0000000..d5962c5 --- /dev/null +++ b/input_processing/labour_supply/do-files/std singles and couples data preparation/2b-couples sample-std model.do @@ -0,0 +1,337 @@ +************************************************************************** +* Poland EM data (PL_2019_b3.txt data) +* Labour supply estimation-get sample for couples and generate the vbls needed for ls (std couples) +************************************************************************* + + +global file_log="${log}/couples_sample-std model" +global n_choices = 4 // 4 choices: no work, plus 3 hours brackets. + + +cd "$local_data" + +capture log close +log using "$file_log", replace +pwd +clear all +set seed 1 //same seed gives same results + +*version 15 + +*estimation of labour supply-loop through :wage1, wage2; hours of work estimation (double loop) +foreach i in 1 2{ //loop begin for wage imputation method +//local i=1 +use "individuals_output_wage`i'",clear + +*use IT_individuals_output_wage2,clear //note that temp_idorigperson2 and other temp vbls are not in the EM output file +//assert bunct_s==0 //making sure unemployment benefit (JSA): bunct_s=0 for every alternatives for everyone + +merge 1:1 idperson using "temp_file.dta" //add additional information +assert _merge==3 +drop _merge + +duplicates report temp_idorigperson2 if temp_couples==1 //count how many unique individuals there are +di r(unique_value) + + +bysort idhh: egen hhcon=sum(ils_dispy) //hh income, should be done before keeping only the target sample + + +gen d40=(dag>=40) + +gen d45=(dag>=45) + +//dummy of living with elderly (aged>=50), including themselves +gen d50=(dag>=50) +lab var d50 "1(male age>=50)" +bysort temp_idorighh:egen d_with_elderly50=total(d50) //up to here d_with_elderly60=the no. of elderly in hh* $n_choices +replace d_with_elderly50=(d_with_elderly50>0) +label variable d_with_elderly50 "1(living with people aged 50+)" + +//dummy of living with elderly (aged>=55), including themselves +gen d55=(dag>=55) +lab var d55 "1(male age>=55)" +bysort temp_idorighh:egen d_with_elderly55=total(d55) //up to here d_with_elderly60=the no. of elderly in hh* $n_choices +replace d_with_elderly55=(d_with_elderly55>0) +label variable d_with_elderly55 "1(living with people aged 55+)" + +//dummy of living with elderly (aged>=60), including themselves +gen d60=(dag>=60) +lab var d60 "1(male age>=60)" +bysort temp_idorighh:egen d_with_elderly60=total(d60) //up to here d_with_elderly60=the no. of elderly in hh* $n_choices +replace d_with_elderly60=(d_with_elderly60>0) +label variable d_with_elderly60 "1(living with people aged 60+)" + +//dummy of living with elderly (aged>=65), including themselves +gen d65=(dag>=65) +lab var d65 "1(male age>=65)" +bysort temp_idorighh:egen d_with_elderly65=total(d65) //up to here d_with_elderly60=the no. of elderly in hh* $n_choices +replace d_with_elderly65=(d_with_elderly65>0) +label variable d_with_elderly65 "1(living with people aged 65+)" + +//dummy of living with elderly (aged>=70), including themselves +gen d70=(dag>=70) +lab var d70 "1(male age>=70)" +bysort temp_idorighh:egen d_with_elderly70=total(d70) //up to here d_with_elderly60=the no. of elderly in hh* $n_choices +replace d_with_elderly70=(d_with_elderly70>0) +label variable d_with_elderly70 "1(living with people aged 70+)" + +/* +//get the original les (les was made to be 5 before running EM for bunct_s=0) +merge 1:1 idperson using les_bunct.dta +keep if _merge==3 +drop _merge +*/ +label variable les "economic status" //temp_les=4: pensioner +gen d_se=(les==2) //dummy of being self-employed +label variable d_se "1(self-employed)" + +******** +keep if temp_couples==1 &temp_choicehh!=. //target sample: flexible couples +//check data structure +bysort temp_idorigperson2: egen double mean_choicehh=mean(temp_choicehh) //compute the mean of flag of hh choice for the same individual +assert mean_choicehh==1/($n_choices^2) //for an individual in flexible couples, 1 option is chosen from ($n_choices)^2 options +assert lhw!=. & yem!=. & yse!=. if temp_singles==1 //make sure lhw, yse, yse are not missing for sample to be included in labour supply estimation + + label variable temp_d_ch "1(children aged 0-17)" + label variable temp_d_ch2 "1(children aged 0-2)" + label variable temp_d_ch6 "1(children aged 3-6)" + label variable temp_d_ch12 "1(children aged 7-12)" + label variable temp_d_ch17 "1(children aged 13-17)" + + + label variable temp_n_ch "number of children aged 0-17" + label variable temp_n_ch2 "number of children aged 0-2" + label variable temp_n_ch6 "number of children aged 3-6" + label variable temp_n_ch12 "number of children aged 7-12" + label variable temp_n_ch17 "number of children aged 13-17" + + +//generation of vbls +gen d_owner=(amrtn==1|amrtn==2) +label variable d_owner "house owner (on mortgage or outright)" + +gen d_owner_out=(amrtn==2) //own outright +label variable d_owner_out "house owner (outright)" + +gen d_owner_mort=(amrtn==1) //own on mortgage +label variable d_owner_mort "house owner (on mortgage)" + +gen d_renter_social=(amrtn==5) //own on mortgage +label variable d_renter_social "house renter (social rented)" + +**************** +add_partner_variables "dag" +rename partner_* sp_* //just to make the names shorter + +gen temp_mean_age=(dag+sp_dag)/2 //partners' mean age +label variable temp_mean_age "partners' mean age" + +gen temp_mean_age2=temp_mean_age^2 //partners' mean age squared +label variable temp_mean_age2 "partners' mean age^2" + +gen leisure=24*7-lhw +replace leisure=0 if leisure<0 //define leisure for utility function +label variable leisure "male leisure" + +//generation of male leisure squared +gen leisure2=leisure^2 +label variable leisure2 "male leisure^2" +gen fixed_cost=(lhw>0) //define a fixed-cost of work (dummy) +label variable fixed_cost "male fixed cost for labour" + +* Generation of hhcon squared + foreach var in hhcon { + gen `var'2=(`var'^2) + label variable `var'2 "`var'^2" + } + +//rescale partners' mean age and age^2 +gen mean_age_100=temp_mean_age/100 +label variable mean_age_100 "partners' mean age/100" + +gen mean_age2_10000=temp_mean_age2/100 +label variable mean_age2_10000 "partners' mean age^2/10000" + +//rescale male age and age^2 +gen age_100=dag/100 +label variable age_100 "male age/100" + +gen age2_10000= temp_age2/10000 +label variable age2_10000 "male age^2/10000" + +//rescale hhcon and hhcon^2 +gen hhcon_100=hhcon/100 +label variable hhcon_100 "income/100" + +gen hhcon2_10000= hhcon2/10000 +label variable hhcon2_10000 "income^2/10000" + +*generation of interactions with household income +global incomex "mean_age_100 mean_age2_10000 temp_n_ch temp_d_ch2 d_owner_out d_owner_mort d_renter_social temp_hhsize temp_dhe_1 temp_dhe_2 temp_dhe_3 temp_dhe_4 temp_dhe_5" +foreach x of varlist $incomex{ +gen hhcon_100_`x'=hhcon_100*`x' +local varlabel : var label `x' +label variable hhcon_100_`x' "income/100#`varlabel'" +} + +/*combining regions +//North West + North East= North +gen temp_north=temp_region1+temp_region2 +lab var temp_north "North" +//South + Islands= South +gen temp_south_islands=temp_region4+temp_region5 +lab var temp_south_islands "South and Islands" +*/ + +*generation of interactions with male fixed cost for labour +global fixedcostx "temp_n_ch temp_d_ch2 temp_d_ch6 temp_d_ch12 temp_d_ch17 d_owner_out d_owner_mort d_renter_social temp_d_deh_L temp_d_deh_M temp_d_deh_H d50 d55 d60 d65 d70 temp_region1 temp_region2 temp_region3 temp_region4 temp_region5 temp_region6 temp_region7 temp_dhe_1 temp_dhe_2 temp_dhe_3 temp_dhe_4 temp_dhe_5" +foreach x of varlist $fixedcostx{ +gen fixc_`x'=fixed_cost*`x' +local varlabel : var label `x' +label variable fixc_`x' "male fixed cost for labour#`varlabel'" +} +*generation of interactions with male leisure +global lx "hhcon_100 age_100 age2_10000 temp_n_ch temp_d_ch2 temp_d_deh_L temp_d_deh_M temp_d_deh_H temp_region1 temp_region2 temp_region3 temp_region4 temp_region5 temp_region6 temp_region7 d_owner_out d_owner_mort d_renter_social temp_hhsize d50 d55 d60 d65 d70 temp_dhe_1 temp_dhe_2 temp_dhe_3 temp_dhe_4 temp_dhe_5" +foreach x of varlist $lx{ +gen lei_`x'=leisure*`x' +local varlabel : var label `x' +label variable lei_`x' "male leisure#`varlabel'" +} + +//social norm? +gen hrs_40=(lhw==40) +label var hrs_40 "1(male's weekly working hours=40)" + +gen hrs_40plus=(lhw>=40) +label var hrs_40plus "1(male's weekly working hours>=40)" + +//experience variable +//gen liwwh_0 = (liwwh==0) //zero experience +gen liwwh_1 = (liwwh>=0 & liwwh<1) //less than a year experience +gen liwwh_2 = (liwwh>=1 & liwwh<5) //1 to 5 years experience +gen liwwh_3 = (liwwh>=5) //5+ years experience +//lab var liwwh_0 "no experience" +lab var liwwh_1 "0-1 years (new entrants)" +lab var liwwh_2 "1-5 years (some experience)" +lab var liwwh_3 "5+ years (highly experienced)" + +gen ln_liwwh = ln(liwwh + 1) + +foreach var in liwwh { + gen `var'2=(`var'^2) + label variable `var'2 "`var'^2" + } + +add_partner_variables "liwwh_1 liwwh_2 liwwh_3 ln_liwwh hrs_40 hrs_40plus liwwh liwwh2 dgn dhe ils_dispy lhw leisure leisure2 lei_hhcon_100 lei_age_100 lei_age2_10000 lei_temp_n_ch lei_temp_d_ch2 lei_temp_d_deh_L lei_temp_d_deh_M lei_temp_d_deh_H lei_temp_region1 lei_temp_region2 lei_temp_region3 lei_temp_region4 lei_temp_region5 lei_temp_region6 lei_temp_region7 lei_d_owner_out lei_d_owner_mort lei_d_renter_social lei_temp_hhsize lei_d50 lei_d55 lei_d60 lei_d65 lei_d70 fixed_cost fixc_temp_n_ch fixc_temp_d_ch2 fixc_temp_d_ch6 fixc_temp_d_ch12 fixc_temp_d_ch17 fixc_d_owner_out fixc_d_owner_mort fixc_d_renter_social fixc_temp_d_deh_L fixc_temp_d_deh_M fixc_temp_d_deh_H fixc_d50 fixc_d55 fixc_d60 fixc_d65 fixc_d70 fixc_temp_region1 fixc_temp_region2 fixc_temp_region3 fixc_temp_region4 fixc_temp_region5 fixc_temp_region6 fixc_temp_region7 temp_d_deh_L temp_d_deh_M temp_d_deh_H age_100 age2_10000 lowas les d_se d50 d55 d60 d65 d70 temp_dhe_1 temp_dhe_2 temp_dhe_3 temp_dhe_4 temp_dhe_5 lei_temp_dhe_1 lei_temp_dhe_2 lei_temp_dhe_3 lei_temp_dhe_4 lei_temp_dhe_5 fixc_temp_dhe_1 fixc_temp_dhe_2 fixc_temp_dhe_3 fixc_temp_dhe_4 fixc_temp_dhe_5" + +rename partner_* sp_* //just to make the names shorter + +label variable ils_dispy "male disposable income" + +*change labels for the female partners ("male"-> "female") +foreach x of varlist liwwh_1 liwwh_2 liwwh_3 ln_liwwh hrs_40 hrs_40plus liwwh liwwh2 dgn dhe ils_dispy lhw leisure leisure2 lei_* fixed_cost fixc_* temp_d_deh_L temp_d_deh_M temp_d_deh_H age_100 age2_10000 temp_dhe_1 temp_dhe_2 temp_dhe_3 temp_dhe_4 temp_dhe_5 { +local varlabel : var label `x' +label variable sp_`x' "fe`varlabel'" +} +lab var liwwh "male work history in months" +lab var sp_liwwh "female work history in months" + +label variable sp_lei_age_100 "female leisure#female age/100" +label variable sp_lei_age2_10000 "female leisure#female age^2/10000" + +label variable sp_hrs_40 "1(female's weekly working hours=40)" +label variable sp_hrs_40plus "1(female's weekly working hours>=40)" + +//v2 update: generating interaction of leisure and sp_leisure +gen lei_sp_lei=leisure*sp_leisure +label variable lei_sp_lei "male leisure#female leisure" + +//to make some labels more clear +label variable lei_temp_d_deh_L "male leisure#male low education (up to lower secondary School; deh = 0-1)" +label variable lei_temp_d_deh_M "male leisure#male middle education (up to post secondary school; deh = 2-4)" +label variable lei_temp_d_deh_H "male leisure#male high education (higher education; deh = 5-6)" + +label variable sp_lei_temp_d_deh_L "female leisure#female low education (up to lower secondary School; deh = 0-1)" +label variable sp_lei_temp_d_deh_M "female leisure#female middle education (up to post secondary school; deh = 2-4)" +label variable sp_lei_temp_d_deh_H "female leisure#female high education (higher education; deh = 5-6)" + +lab var sp_lei_d50 "female leisure#1(female age>=50)" +lab var sp_lei_d55 "female leisure#1(female age>=55)" +lab var sp_lei_d60 "female leisure#1(female age>=60)" +lab var sp_lei_d65 "female leisure#1(female age>=65)" +lab var sp_lei_d70 "female leisure#1(female age>=70)" + +/* +preserve +keep if dgn==0 +drop i_* //Stata refused to rename some of them probably because they are too long +drop tu_* +rename * sp_* +rename sp_temp_idorigpartner temp_idorigperson2 //for the purpose of merging with their male partners +gsort sp_temp_idorigperson2 sp_lhw //Place observations in ascending order of lhw within ascending order of person +bysort sp_temp_idorigperson2:egen sp_seq=seq() //give each working regime a label for the purpose +save IT_sp_output_wage`i',replace //this file contains the female partners' information BUG:NO 0 working regime!!!(fixed) +restore + +*======================================================================= +* create combinations of hh labour supply regimes +* (each line includes info of both partners in hh) +*======================================================================= +keep if dgn==1 //keep only male partners +expand 4 //4 choices for each of the 4 regimes for male partners +sort _all //sort to keep same order in seq() + +bysort temp_idorigperson2 idperson lhw:egen sp_seq=seq() + +merge m:1 temp_idorigperson2 sp_seq using IT_sp_output_wage1 +keep if _merge==3 //keep only those whose partners' info is available in the data +*/ +*------------------------------------------------------------------------------------------------------------- +*couples working regimes: lhw*sp_lhw (4*4=16 choices) +*------------------------------------------------------------------------------------------------------------- +gsort temp_idorigperson2 lhw sp_lhw //Place observations in ascending order of lhw sp_lhw within ascending order of person +bysort temp_idorigperson2:egen temp_hh_alt=seq() //give each working regime a label for the purpose +//label var temp_hh_alt "household working regimes" +label var temp_hh_alt "weekly hours worked" + +label define temp_lab_hh_alt 1 "(0,0)" 2 "(0,20)" 3 "(0,40)" 4 "(0,50)" /// + 5 "(20,0)" 6 "(20,20)" 7 "(20,40)" 8 "(20,50)" /// + 9 "(40,0)" 10 "(40,20)" 11 "(40,40)" 12 "(40,50)" /// + 13 "(50,0)" 14 "(50,20)" 15 "(50,40)" 16 "(50,50)" + +/* +label define temp_lab_hh_alt 1 "(0,0)" 2 " (0,20)" 3 "(0,30)" 4 "(0,36)" 5 "(0,40)" /// +6 "(30,0)" 7 "(30,20)" 8 "(30,30)" 9 "(30,36)" 10 "(30,40)" /// +11 "(36,0)" 12 "(36,20)" 13 "(36,30)" 14 "(36,36)" 15 "(36,40)" /// +16 "(40,0)" 17 "(40,20)" 18 "(40,30)" 19 "(40,36)" 20 "(40,40)" /// +21 "(50,0)" 22 "(50,20)" 23 "(50,30)" 24 "(50,36)" 25 "(50,40)" +*/ + +label values temp_hh_alt temp_lab_hh_alt +keep if dgn==1 +duplicates report temp_idorigperson2 if temp_couples==1 //count how many unique individuals there are +di r(unique_value) + +drop if sp_dgn==. +duplicates report temp_idorigperson2 if temp_couples==1 //count how many unique individuals there are +di r(unique_value) + +drop if sp_dgn==1 +duplicates report temp_idorigperson2 if temp_couples==1 //count how many unique individuals there are +di r(unique_value) + +assert dgn==1 &sp_dgn==0 //assert partners are of different genders +bysort temp_idorigperson2: egen min_hhcon=min(hhcon) +drop if min_hhcon<=0 //consumption is not allowed to be 0 or negative for lslogit + +duplicates report temp_idorigperson2 if temp_couples==1 //count how many unique individuals there are +di r(unique_value) + +gen sim_flag=0 //new in v8 + + +save couples_wage`i',replace +} //loop end for wage imputation method + +log close diff --git a/input_processing/labour_supply/do-files/std singles and couples data preparation/3a-EM single wage elasticity-std model.do b/input_processing/labour_supply/do-files/std singles and couples data preparation/3a-EM single wage elasticity-std model.do new file mode 100644 index 0000000..8bb0b9e --- /dev/null +++ b/input_processing/labour_supply/do-files/std singles and couples data preparation/3a-EM single wage elasticity-std model.do @@ -0,0 +1,96 @@ +************************************************************************** +* Poland EM data (PL_2019_b3.txt data) +*run EM to get the ils_dispy for sample of singles resulting from a 10% increase in gross wage +************************************************************************ + +global file_log="${log}/EM_singles_elast" + +cd "$local_data" + +capture log close +log using "$file_log", replace +pwd + + +global n_choices = 4 // 4 choices: no work, plus 3 hours brackets. +global n_workchoices = $n_choices - 1 // 3 choices with positive supply of hours, 1 choice with 0 hours. +//update 1/2/2021: when Extract the sample of "singles" and define variables, save separately as sim_singles_indep_110_IT_individuals_output_wage`i' +//& sim_singles_dep_110_IT_individuals_output_wage`i' + +foreach i in 1 2{ //loop begin for wage imputation method +//local i=1 //only do for wage1 +use individuals_wage`i',clear +merge 1:1 idperson using temp_file.dta //add additional information +drop _merge +keep if temp_alt_n==1 //reduce EUROMOD burden + +replace yivwg=1.1*yivwg //to be safe (new) +*replace yem=1.1*yem //increase gross wage by 10% +*replace yse=1.1*yse //increase gross wage by 10% +replace yempj=1.1*yempj +replace yemtj=1.1*yemtj +replace yseag=1.1*yseag +replace ysebs=1.1*ysebs + +//for self-employed income, change yse, yseev, ysenr to be on the safe side, and then EM decides which vbls use (either yseev+ysenr or yse) depending on the switch of the TCA +/*replace yseev=1.1*yseev //increase gross wage by 10% +replace ysenr=1.1*ysenr //increase gross wage by 10%*/ + +drop temp* +sort idhh +export delimited "$em_input\$file_input.txt", replace nolabel delim(tab) //create input data for EUROMOD + +************************************************************ +* Run EUROMOD with Stata +************************************************************ +version 13 +* Call EUROMOD + +capture erase "${em_output}\$file_output.txt" //erase previous output file, this is done in case EUROMOD call from Stata fails, to be sure we are not opening an early run of the model + +shell "${em_exe}" -emPath "${em_models}" -sys PL_2018 -data PL_2019_b3 -forceOutputInEuro //call EUROMOD 1:Program to call 2: path for folder 3: system name 4: dataset to use + +*import EUROMOD RUN + +import delimited "${em_output}\$file_output.txt", clear //import data from txt file in output folder +gen sim_flag=1 //to indicate that these are simulated observations +rename ils_dispy sim_ils_dispy +rename yem sim_yem +rename yse sim_yse +bysort idhh: egen sim_hhcon=sum(sim_ils_dispy) //hh income, should be done before keeping only the target sample +keep idperson sim_ils_dispy sim_hhcon sim_yem sim_yse +save sim_110_individuals_output_wage`i',replace +} //loop end for wage imputation method + +*======================================================================= +* Extract the sample of "singles" and define variables +*======================================================================= +foreach i in 1 2{ //loop begin for wage imputation method +//local i=1 +use "sim_110_individuals_output_wage`i'",clear +merge 1:1 idperson using "singles_wage`i'.dta" +keep if _merge==3 +drop _merge +su hhcon sim_hhcon +replace hhcon=sim_hhcon //make hhcon=simulated hhcon +assert sim_hhcon==hhcon +replace yem=sim_yem +replace yse=sim_yse +replace ils_dispy=sim_ils_dispy //new + +drop sim_* +gen sim_flag=1 +//singles_indep +preserve +keep if temp_singles_indep==1 +save "sim_singles_indep_110_individuals_output_wage`i'",replace +restore +//singles_dep +preserve +keep if temp_singles_dep==1 +save "sim_singles_dep_110_individuals_output_wage`i'",replace +restore + +} //loop end for wage imputation method + +log close diff --git a/input_processing/labour_supply/do-files/std singles and couples data preparation/3b-EM couple wage elasticity-std model.do b/input_processing/labour_supply/do-files/std singles and couples data preparation/3b-EM couple wage elasticity-std model.do new file mode 100644 index 0000000..427e544 --- /dev/null +++ b/input_processing/labour_supply/do-files/std singles and couples data preparation/3b-EM couple wage elasticity-std model.do @@ -0,0 +1,117 @@ +************************************************************************** +* Poland EM data (PL_2019_b3.txt data) +*run EM to get the ils_dispy for sample of couples resulting from a 10% increase in gross wage +************************************************************************ + +global file_log="${log}/EM_couples_elast" + +cd "$local_data" + +capture log close +log using "$file_log", replace +pwd + +global n_choices = 4 // 4 choices: no work, plus 3 hours brackets. +global n_workchoices = $n_choices - 1 // 3 choices with positive supply of hours, 1 choice with 0 hours. + +foreach i in 1 2{ //loop begin for wage imputation method +//local i=1 //only for wage1 +foreach gender in 0 1{ +use individuals_wage`i',clear +merge 1:1 idperson using temp_file.dta //add additional information +drop _merge +keep if temp_alt_nsq==1 //reduce EUROMOD burden +replace yivwg=1.1*yivwg if dgn==`gender' & temp_couples==1 //to be safe (new) +*replace yem=1.1*yem if dgn==`gender' & temp_couples==1 //increase gross wage by 10% +*replace yse=1.1*yse if dgn==`gender' & temp_couples==1 //increase gross wage by 10% +replace yempj=1.1*yempj if dgn==`gender' & temp_couples==1 +replace yemtj=1.1*yemtj if dgn==`gender' & temp_couples==1 +replace yseag=1.1*yseag if dgn==`gender' & temp_couples==1 +replace ysebs=1.1*ysebs if dgn==`gender' & temp_couples==1 + +/*//for self-employed income, change yse, yseev, ysenr to be on the safe side, and then EM decides which vbls use (either yseev+ysenr or yse) depending on the switch of the TCA +replace yse=1.1*yseev if dgn==`gender' & temp_couples==1 //increase gross wage by 10% +replace yse=1.1*ysenr if dgn==`gender' & temp_couples==1 //increase gross wage by 10% +*/ + +drop temp* +sort idhh + +export delimited "$em_input\$file_input.txt", replace nolabel delim(tab) //create input data for EUROMOD +************************************************************ +* Run EUROMOD with Stata +************************************************************ +version 13 +* Call EUROMOD + +capture erase "${em_output}\$file_output.txt" //erase previous output file, this is done in case EUROMOD call from Stata fails, to be sure we are not opening an early run of the model + +shell "${em_exe}" -emPath "${em_models}" -sys PL_2018 -data PL_2019_b3 -forceOutputInEuro //call EUROMOD 1:Program to call 2: path for folder 3: system name 4: dataset to use + +*import EUROMOD RUN +import delimited "${em_output}\$file_output.txt", clear //import data from txt file in output folder +gen sim_flag=1 //to indicate that these are simulated observations +rename ils_dispy sim_ils_dispy +rename yem sim_yem +rename yse sim_yse +bysort idhh: egen sim_hhcon=sum(sim_ils_dispy) //hh income, should be done before keeping only the target sample +keep if dgn==`gender' //important for couples' data + +keep idperson idpartner sim_ils_dispy sim_hhcon sim_yem sim_yse +if (`gender' == 0){ +save "sim_110female_individuals_output_wage`i'",replace +} +else{ +save "sim_110male_individuals_output_wage`i'",replace +} + +} //loop end for gender +} //loop end for wage imputation method + +*======================================================================= +* Extract the sample of couples and define variables (with simulated female wage) +*======================================================================= +foreach i in 1 2{ //loop begin for wage imputation method +//local i=1 //only for wage1 +use "sim_110female_individuals_output_wage`i'",clear +drop idperson +rename idpartner idperson //for the puropose of merging with their partners +merge m:1 idperson using "couples_wage`i'.dta" +keep if _merge==3 //only keep the target sample of couples +drop _merge +su hhcon sim_hhcon +replace hhcon=sim_hhcon //make hhcon=simulated hhcon +assert sim_hhcon==hhcon +drop sim_yem sim_yse //there is no such vbls for female partners in IT_couples.dta +*replace sp_yem=sim_yem +*replace sp_yse=sim_yse +replace sp_ils_dispy=sim_ils_dispy //new + +drop sim_* +gen sim_flag=10 //indicate that this is with simulated female partners wage +duplicates report idperson //no duplicates +save "sim_couples_110female_output_wage`i'",replace +} //loop end for wage imputation method + +*======================================================================= +* Extract the sample of couples and define variables (with simulated male wage) +*======================================================================= +foreach i in 1 2{ //loop begin for wage imputation method +//local i=1 //only for wage1 +use "sim_110male_individuals_output_wage`i'",clear +merge 1:1 idperson using "couples_wage`i'.dta" +keep if _merge==3 //only keep the target sample of couples +drop _merge +su hhcon sim_hhcon +replace hhcon=sim_hhcon //make hhcon=simulated hhcon +assert sim_hhcon==hhcon +replace yem=sim_yem +replace yse=sim_yse +replace ils_dispy=sim_ils_dispy //new + +drop sim_* +gen sim_flag=11 //indicate that this is with simulated male partners wage +save "sim_couples_110male_output_wage`i'",replace +} //loop end for wage imputation method + +log close