*! version 1.0.1 27Sep2016 *! version 1.0.2 05Jun2017 major changes in the code and how the whole routine works, added exponential and parameters options *! version 1.0.3 14Mar2018 add the OMEGA option in order to yield the estimates of omega according to De Loecker & Warzynski (AER, 2012) *! version 1.1.0 19May2020 add the markups option (+ inputvar() + correction) *! authors: Gabriele Rovigatti, University of Chicago Booth School of Business & EIEF, Rome, Italy. mailto: gabriele.rovigatti@gmail.com *! Vincenzo Mollisi, Bolzano University, Bolzano, Italy & Tor Vergata University, Rome, Italy. mailto: vincenzo.mollisi@gmail.com /*************************************************************************** ** Stata program for prodest Postestimation ** ** Programmed by: Gabriele Rovigatti **************************************************************************/ cap program drop prodest_p program define prodest_p, sortpreserve eclass version 10.0 syntax [anything] [if] [in] [, /// RESIDuals /// EXPonential /// PARameters /// OMEGA /// MARKups /// INPUTvar(varlist numeric min=1 max=1) /// CORRected /// ] marksample touse // this is not e(sample) tempvar esample qui gen byte esample' = e(sample) loc varlist anything' loc mod = "e(PFtype)'" loc fsres = "e(FSres)'" loc free = "e(free)'" if "e(model)'" == "grossoutput"{ loc proxy = "e(proxy)'" loc free "free' proxy'" } loc state = "e(state)'" ************************************************************************************************ ********************* PART 1: MARKUPS ESTIMATION ************************ ************************************************************************************************ if !mi("markups'"){ /* check for correct usage of options */ if !mi("corrected'") & mi("fsres'"){ // correction à la DLW only available with first-stage residuals di as error "Markup correction requires launching prodest with 'fsresiduals()' option" exit 198 } if !:list inputvar in free'{ // check whether the input variable specified is in the list of free variables di as error " should be either a free or a proxy variables used in the estimation" exit 198 } cap confirm var varlist' // if the variable already exists if !_rc{ di as error "varlist' already exists" exit 198 } if mi("varlist'"){ // check the outcome variable: if it is missing, use a pre-specified _mkup[number] variable loc c = 0 while (1){ loc ++c loc varlist _mkupc' cap confirm var varlist' if (_rc != 0) continue, break } di as error "You should specify to store the estimated markups. They will be stored in varlist' now" } ********* ROUTINE START ************** tempvar theta alpha /* generate the input share, either "raw" or corrected by the first-stage residuals as suggested by DLW */ loc lhs e(depvar)' // this is the output - in logs qui g alpha' = exp(inputvar') / exp(lhs') if !mi("corrected'"){ qui replace alpha' = alpha' * exp(fsres') } /* Generate the elasticity parameter - either the estimated beta (Cobb-Douglas) or a function of it (Translog) */ if "mod'" == "Cobb-Douglas"{ /* PART I: COBB-DOUGLAS */ qui g theta' = _b[inputvar'] // } else { /* PART II: TRANSLOG */ tempname beta mat beta' = e(b) // extract the estimated betas loc controls = "e(controls)'" loc transvars free' state' controls' loc translogNum: word count transvars' loc n = 1 // regenerate the variables used in the routine in order to fit the values foreach x of local transvars{ tempvar var_n' betavar_n' qui g var_n'' = x' loc ++n } forv i = 1/translogNum'{ forv j = i'/translogNum'{ tempvar var_i'j' beta_i'j' cap g var_i'j'' = (var_i'' * var_j'') cap g beta_i'j'' = beta'[1,n'] loc ++n } } loc varnum: word count free' state' loc inputpos: list posof "inputvar'" in free // this is the number of the input variable within the free vars forv j = 1/varnum'{ if inputpos' != j'{ /* generate the cross variables part only */ cap confirm variable beta_inputpos'j'' if !_rc{ loc remainder remainder' + (beta_inputpos'j'' * var_j'') } else{ loc remainder remainder' + (beta_j'inputpos'' * var_j'') } } } qui gen theta' = beta'[1,inputpos'] + (2 * beta_inputpos'inputpos'' * var_inputpos'') remainder' // the elasticity for translog is defined as beta_Wtranslog = beta_w + 2*beta_ww * W + beta_wx * X, and here we use the previously generated variables and weight them by the ith variable } /* Compute the Markups */ g varlist' = theta' / alpha' if' // compute the markups, and save the relative variable } else{ ************************************************************************************************ **************** PART 2: TFP/RESIDUALS/PARAMETERS ESTIMATION ************* ************************************************************************************************ /* check for options in launching command */ if ( mi("residuals'") & mi("exponential'") & mi("parameters'") & mi("omega'") & mi("varlist'")){ di as error "You must specify , RESIDuals, EXPonential, PARameters or OMEGA" exit 198 } /* check for correct usage of options */ if ( (!mi("residuals'") | !mi("exponential'") | !mi("omega'")) & !mi("parameters'")){ di as error "the 'parameters' option cannot be used with other options" exit 198 } if !mi("omega'") & mi("fsres'"){ di as error "the 'omega' option can only be used after launching prodest with 'fsresiduals(newvar)' option" exit 198 } if mi("parameters'") & mi("varlist'"){ di as error "You must specify newvarname to store results" exit 198 } /* straight predict: yields yhat */ if (mi("residuals'") & mi("exponential'") & mi("parameters'") & mi("omega'")){ loc straightpredict "y" } if "mod'" == "Cobb-Douglas"{ /* PART I: COBB-DOUGLAS */ if (mi("parameters'")) { tempname beta mat beta' = e(b) tempvar rhs mat score double rhs' = beta' loc lhs e(depvar)' if !mi("exponential'"){ qui gen varlist' = exp(lhs' - rhs') if' } else if !mi("omega'"){ /* generate estimates of omega like: \hat{W} = \hat{phi} - f(k,l,\hat{beta}) */ qui gen varlist' = lhs' - fsres' - rhs' if' } else if "straightpredict'" == "y"{ qui gen varlist' = rhs' } else{ /* residuals */ qui gen varlist' = lhs' - rhs' if' } } else{ /* 'parameters' with cobb-douglas PF yields the results' table */ _coef_table, level(\$S_level) } } else { /* PART II: TRANSLOG */ loc lhs e(depvar)' loc free = "e(free)'" if "e(model)'" == "grossoutput"{ loc proxy = "e(proxy)'" loc free "free' proxy'" } loc state = "e(state)'" loc controls = "e(controls)'" loc transvars free' state' controls' loc translogNum: word count transvars' tempname beta mat beta' = e(b) // extract the estimated betas loc n = 1 // regenerate the variables used in the routine in order to fit the values foreach x of local transvars{ tempvar var_n' betavar_n' *qui g betavar_n'' = beta'[1,n'] * x' qui g betavar_n'' = _b[x'] * x' qui g var_n'' = x' loc fit fit' - betavar_n'' loc ++n } forv i = 1/translogNum'{ forv j = i'/translogNum'{ /* i' */ tempvar var_i'j' betavar_i'j' beta_i'j' cap g betavar_i'j'' = beta'[1,n'] * (var_i'' * var_j'') cap g var_i'j'' = (var_i'' * var_j'') cap g beta_i'j'' = beta'[1,n'] loc fit fit' - betavar_i'j'' loc ++n } } if !mi("exponential'") { qui g varlist' = exp(lhs' fit') if' // here generate the predicted residuals -- exponential } else if !mi("omega'"){ /* generate estimates of omega like: \hat{W} = \hat{phi} - f(k,l,\hat{beta}) */ qui gen varlist' = lhs' - fsres' fit' if' } else if "straightpredict'" == "y"{ qui gen varlist' = -(fit') } else if !mi("residuals'"){ qui g varlist' = lhs' fit' if' // here generate the predicted residuals } else{ /* in case of 'parameters' option */ loc freenum: word count free' loc statenum: word count state' loc totnum: word count free' state' loc n = 0 forv i = 1/totnum'{ forv j = 1/totnum'{ loc ++n if i' != j'{ /* generate the cross variables part only */ cap confirm variable betavar_i'j'' if !_rc{ loc remainder remainder' + beta_i'j'' * var_j'' /* *var_i'' */ } else{ loc remainder remainder' + beta_j'i'' * var_j'' } } } tempvar betafit_i' // the parameter for translog is defined as beta_Wtranslog = beta_w + 2*beta_ww * W + beta_wx * X qui gen betafit_i'' = beta'[1,i'] + 2 * beta_i'i'' * var_i'' remainder' // here we use the previously generated variables and weight them by the ith variable -- *var_i'' qui su betafit_i'', meanonly loc beta_i': di %6.3f r(mean)' if !mi("varlist'"){ /* if the user specified the varlist to store the elasticities, generate the variable(s) */ loc newvarname: "varlist'_i'" qui g newvarname' = betafit_i'' } loc remainder "" } di _n _n di as text "{hline 75}" di as text "Translog elasticity estimates" _continue di _col(49) "prodest postestimation" di as text "{hline 75}" di as text "Elasticity Parameter" _continue di _col(49) "Value" di as text "{hline 75}" loc i = 1 foreach var of varlist free' state'{ di as text "beta_var'" _continue di _col(49) "beta_i''" eret loc beta_var' "beta_i''" loc ++i } di as text "{hline 75}" } } } end