/* divratio version 14.2 version date 04nov2022 This file outputs diversion ratios based on the semiparametric model (see Raval, Rosenbaum, and Tenn (2017)), with flexible options. Arguments: 1. a_side - Indicator variable for which observations belong to the A-side 2. b_side - Indicator variable for which observations belong to the B-side 3. hosp_id - Hospital ID (e.g., the name of the medical center) 4. owner_id - Ownership structure ID (e.g., the common healthcare group, or "system", that owns the hospitals in hosp_id) 5. geo - Geographic reference categorical variable (for example, this could be ZIP code) 6. prod - Products offered by the firms to overlap (for example, this could be DRG or MDC) Options: groups(varlist) - Patient characteristic variables to define groups. wtp - If specified, also conducts WTP analysis. weight(varlist) - Weight for each observation in the data. For example, if data is aggregated, specify as variable that represents number of discharges per observation. ungrouped(string) - Instructions on what to do with observations that cannot be grouped. Can either keep them ("keep") or drop them ("drop"). If unspecified, will drop ungrouped observations. allow_within - Allows hospital-to-hospital diversions within the same ownership group. replacement - Groups variables based off of resampling with replacement. geo_ref(string) - Identify whether geographic region has A-side focus ("a-side"), B-side focus ("b-side"), combined ("combined") or union focus ("union"). Default is union focus. If all geographic regions to be used, specify `svc_pct' as 100. prod_ref(string) - Identify whether products considered have A-side focus ("a-side"), B-side focus ("b-side"), or overlap focus ("overlap"). Default is overlap focus. If all products are to be used, input "union". svc_pct(integer 100) - Percent service area based on "geo_ref" specification, will use 100% service area as default. min_group_size(integer 20) - Minimum number of observations in a bin, will use 20 as a default. Represents the tuning parameter in Raval, et. al. outside_cutoff(real 0.005) - Cutoff in terms of relative size (share) to be considered as an "outside option", will use 0.005 as default. topcode(real 0.99) - A percentage to ensure probabilities are < 1 for WTP calculations (since otherwise WTP is undefined). inter_input(string) - Input file from previous intermediate step (X Service Area Group Probabilities.dta) to save time in later executions of the program. save_inter(string) - Directory to save intermediate files. Default will not save the files. output(string) - Directory to save the results. Default will not save the file. disp_str(integer 30) - Number of string characters to display in results. Version updates: 1.1 - adds in geo_ref and prod_ref to allow flexibility with respect to which side's geography/products to focus on. 1.2 - fixes error when bin sizes are too small; keeps parties' firm location even when its share is below the threshold. 1.3 - adds in a way to compute diversions with aggregated data. 1.4 - adds in option to exclude diversions within firm, add in inter_input(). 1.5 - alters some options to use strings instead of integers, adds in binning without resampling. 1.6 - adds "if" option, cleans up output, and includes command to drop unbinned observations. Also includes "combined" option for geo_ref command. 1.7 - adds in WTP results. Author: Chris Lau, clau@ftc.gov, chris.vlau@gmail.com */ program define divratio, rclass version 14.2 syntax varlist(min=6) [if] [, groups(varlist) wtp weight(varlist) allow_within ungrouped(string) replacement geo_ref(string) prod_ref(string) svc_pct(integer 100) outside_cutoff(real 0.005) topcode(real 0.99) min_group_size(integer 20) inter_input(string) save_inter(string) output(string) disp_str(integer 30)] // Parse variable list // tokenize `varlist' args a_side b_side hosp_id owner_id geo prod // Step 0: Display primatives // display("") display("{bf:Semiparametric Estimation}") display("") display("{ul:Selected Options:}") // Set locals for file names // if "`output'" != "" { qui local results = "`output'" display("- Diversion results are saved to: `results'") if "`wtp'" != "" { qui local wtp_results = "`save_inter'\Results - Willingness-to-pay.dta" display("- WTP results are saved to: `wtp_results'") } } if "`save_inter'" != "" { qui local svc_area_name_1 = "`save_inter'\\RAW - A-side `svc_pct' Service Area Regions.dta" qui local svc_area_name_2 = "`save_inter'\\RAW - B-side `svc_pct' Service Area Regions.dta" qui local svc_area_samp_1 = "`save_inter'\\RAW - A-side `svc_pct' Service Area Sample.dta" qui local svc_area_samp_2 = "`save_inter'\\RAW - B-side `svc_pct' Service Area Sample.dta" qui local svc_area_name = "`save_inter'\\RAW - Combined `svc_pct' Service Area Regions.dta" qui local svc_area_samp = "`save_inter'\\RAW - Combined `svc_pct' Service Area Sample.dta" qui local prods_1 = "`save_inter'\\RAW - A-side Products.dta" qui local prods_2 = "`save_inter'\\RAW - B-side Products.dta" qui local overlapprods = "`save_inter'\\RAW - Overlapping Products.dta" qui local full_samp = "`save_inter'\\RAW - `svc_pct' Service Area Overlapping Products Sample.dta" qui local choiceset = "`save_inter'\\RAW - Choice Set.dta" qui local choices_samp = "`save_inter'\\RAW - Panel Estimation Sample.dta" qui local bindata_final "`save_inter'\\Results - Choice Probabilities.dta" qui local tempdata = "`save_inter'\\tempdata.dta" qui local bindata = "`save_inter'\\RAW - Probabilities by Group.dta" if "`wtp'" != "" { qui local wtp_raw = "`save_inter'\\RAW - All Pre- and Post-merger WTP.dta" } if "`output'" == "" { qui local results = "`save_inter'\Results - Diversions.dta" display("- Diversion Results are saved to: `results'") if "`wtp'" != "" { qui local wtp_results = "`save_inter'\Results - Willingness-to-pay.dta" display("- WTP results are saved to: `wtp_results'") } } } // Display selected options // if "`inter_input'" == "" { if "`agg'" == "" { qui gen num = 1 } else { display("- Data is aggregated; variable '`agg'' represents number of individuals") qui gen num = `agg' } if "`geo_ref'" == "a-side" { display("- Reference service area is: A-side") } else if "`geo_ref'" == "b-side" { display("- Reference service area is: B-side") } else if "`geo_ref'" == "combined" { display("- Reference service area is: Combined") } else { display("- Reference service area is: Union") } if "`prod_ref'" == "a-side" { display("- Reference product is for: A-side") } else if "`prod_ref'" == "b-side" { display("- Reference product is for: B-side") } else if "`prod_ref'" == "union" { display("- Reference product is for: Union") } else { display("- Reference product is for: Overlapping") } display("- Service area: `svc_pct'%") if length("`if'") > 0 { local restrict = subinstr("`if'", "if ", "", 1) display("- Restricted on: `restrict'") } if "`groups'" != "" { display("- Variables used to create groups: `groups'") } else { display("- Variables used to create groups: None") } display("- Minimum group size: `min_group_size'") display("- Minimum share to be counted as a choice: `outside_cutoff'") if "`replacement'" == "" { display("- Groups constructed without replacement") } else { display("- Groups constructed with replacement") } if "`allow_within'" != "" { display("- Allow within system diversion: Yes") } else { display("- Allow within system diversion: No") } if "`wtp'" != "" { display("- Topcode for WTP: `topcode'") } // Step 1: Find service areas // *timer on 1 ** Identify reference firms ** capture drop ref_firm* qui gen ref_firm1 = (`a_side' == 1) local ref_firm1_name = "A-side" qui gen ref_firm2 = (`b_side' == 1) local ref_firm2_name = "B-side" display "" display("{ul:Intermediate Calculations:}") if "`geo_ref'" == "combined" { if `svc_pct' < 100 { preserve if length("`if'") > 0 { quietly keep `if' } qui gen num_ref_firm = num*(ref_firm1 + ref_firm2) collapse (sum) obs = num_ref_firm (sum) totalObs = num, by(`geo') * Calculate geo and firm shares * qui egen total = sum(obs) qui gen geoshare = obs / total qui gen firmshare = obs/totalObs * Sort by cumulative share * qui gsort -geoshare `geo' qui gen cumshare = sum(geoshare) * Create market shares * qui gen obsSum = sum(obs) qui gen totalObsSum = sum(totalObs) qui gen market_share = obsSum/totalObsSum * Drop observations not in service areas * qui gen svc = (cumshare[_n-1] < `svc_pct'/100) qui replace svc = 1 if _n == 1 qui keep if svc == 1 * Keep relative variables * qui keep `geo' cumshare firmshare totalObs geoshare obs market_share * Display service area stats * qui count display "- There are " r(N) " geographic regions in the combined `svc_pct'% service area." * Save file * if "`save_inter'" == "" { qui tempfile svc_area_name qui save "`svc_area_name'" } else { qui save "`svc_area_name'", replace } restore } preserve if length("`if'") > 0 { quietly keep `if' } * Keep observations that are in the service area * capture drop _merge if `svc_pct' < 100 { qui merge m:1 `geo' using "`svc_area_name'", keep(matched) keepusing(`geo') nogen } if "`save_inter'" == "" { qui tempfile svc_area_samp qui save "`svc_area_samp'" } else { qui save "`svc_area_samp'", replace } forvalues svc_base = 1(1)2 { qui use "`svc_area_samp'", clear if "`prod_ref'" != "union" { * Keep products that are in the service area * qui keep if ref_firm`svc_base' == 1 } qui keep `prod' qui duplicates drop if "`save_inter'" == "" { qui tempfile prods_`svc_base' qui save "`prods_`svc_base''" } else { qui save "`prods_`svc_base''", replace } } restore } if "`geo_ref'" != "combined" { forvalues svc_base = 1(1)2 { ** Identify service area for each side ** if `svc_pct' < 100 { preserve if length("`if'") > 0 { quietly keep `if' } qui gen num_ref_firm`svc_base' = num*ref_firm`svc_base' collapse (sum) obs = num_ref_firm`svc_base' (sum) totalObs = num, by(`geo') * Calculate geo and firm shares * qui egen total = sum(obs) qui gen geoshare = obs / total qui gen firmshare = obs/totalObs * Sort by cumulative share * qui gsort -geoshare `geo' qui gen cumshare = sum(geoshare) * Create market shares * qui gen obsSum = sum(obs) qui gen totalObsSum = sum(totalObs) qui gen market_share = obsSum/totalObsSum * Drop observations not in service areas * qui gen svc = (cumshare[_n-1] < `svc_pct'/100) qui replace svc = 1 if _n == 1 qui keep if svc == 1 * Keep relative variables * qui keep `geo' cumshare firmshare totalObs geoshare obs market_share * Display service area stats * qui count if "`geo_ref'" == lower("`ref_firm`svc_base'_name'") | "`geo_ref'" == "union" { display "- There are " r(N) " geographic regions in the `ref_firm`svc_base'_name''s `svc_pct'% service area." } * Save file * if "`save_inter'" == "" { qui tempfile svc_area_name_`svc_base' qui save "`svc_area_name_`svc_base''" } else { qui save "`svc_area_name_`svc_base''", replace } restore } preserve if length("`if'") > 0 { quietly keep `if' } * Keep observations that are in the service area * capture drop _merge if `svc_pct' < 100 { qui merge m:1 `geo' using "`svc_area_name_`svc_base''", keep(matched) keepusing(`geo') nogen } if "`save_inter'" == "" { qui tempfile svc_area_samp_`svc_base' qui save "`svc_area_samp_`svc_base''" } else { qui save "`svc_area_samp_`svc_base''", replace } if "`prod_ref'" != "union" { * Keep products that are in the service area * qui keep if ref_firm`svc_base' == 1 } qui keep `prod' qui duplicates drop if "`save_inter'" == "" { qui tempfile prods_`svc_base' qui save "`prods_`svc_base''" } else { qui save "`prods_`svc_base''", replace } restore } } *timer off 1 *timer list 1 // Step 2: Identify relevant products // // If `prod_ref' == "overlap", (default) use overlapping products of A-side and B-side. // If `prod_ref' == "a-side", use all products from A-side. // If `prod_ref' == "b-side", use all products from B-side. // If `prod_ref' == "union", use all products. *timer on 2 preserve if "`prod_ref'" == "a-side" { qui use "`prods_1'", clear } else if "`prod_ref'" == "b-side" { qui use "`prods_2'", clear } else{ qui use "`prods_1'", clear if "`prod_ref'" == "union" { qui merge 1:1 `prod' using "`prods_2'", nogen } else { qui merge 1:1 `prod' using "`prods_2'", keep(3) nogen } } * Display overlapping product stats * qui count if "`prod_ref'" == "a-side" { display "- There are " r(N) " products for the A-side." } else if "`prod_ref'" == "b-side" { display "- There are " r(N) " products for the B-side." } else if "`prod_ref'" == "union" { display "- All prodcuts are being used." } else { display "- There are " r(N) " overlapping products between the A-side and B-side." } * Save file * if "`save_inter'" == "" { qui tempfile overlapprods qui save "`overlapprods'" } else { qui save "`overlapprods'", replace } restore * Create usable dataset limiting to observations within service area and relevant products * preserve if "`geo_ref'" == "a-side" { qui use "`svc_area_samp_1'", clear } else if "`geo_ref'" == "b-side" { qui use "`svc_area_samp_2'", clear } else if "`geo_ref'" == "combined" { qui use "`svc_area_samp'", clear } else { qui use "`svc_area_samp_1'", clear qui append using "`svc_area_samp_2'" } qui duplicates drop qui merge m:1 `prod' using "`overlapprods'", keep(3) nogen qui drop ref_firm* qui tabstat num, s(sum) save matrix A = r(StatTotal) qui scalar N = A[1,1] display "- There are " N " customers in the estimation sample." * Save file * if "`save_inter'" == "" { qui tempfile full_samp qui save "`full_samp'" } else { qui save "`full_samp'", replace } restore *timer off 2 *timer list 2 // Step 3: Create choice sets for each patient // *timer on 3 preserve * Ideintify relevant choice set * qui use "`full_samp'", clear qui gen purchase = num qui collapse (sum) purchase, by(`hosp_id' `owner_id' `a_side' `b_side') qui egen totPurch = sum(purchase) qui gen purchShare = purchase/totPurch * Discard firm locations where there exists a small share * qui keep if purchShare > `outside_cutoff' | `a_side' == 1 | `b_side' == 1 * Add in outside option qui set obs `=_N+1' qui local last = _N qui replace `hosp_id' = "Outside" in `last' qui gen cross = 1 * Display choice set stats * qui count display "- There are " r(N)-1 " firm locations in the choice set." * Save File * if "`save_inter'" == "" { qui tempfile choiceset qui save "`choiceset'" } else { qui save "`choiceset'", replace } * Cross choiec set with sample observations * qui use "`full_samp'", clear qui gen cross = 1 gen id = _n qui rename `hosp_id' `hosp_id'_chosen drop `a_side' `b_side' `owner_id' qui joinby cross using "`choiceset'" * Create variable indicating which firm location was observably chosen * qui gen obs_choice = num*(`hosp_id' == `hosp_id'_chosen) qui egen x = sum(obs_choice), by(id) qui replace obs_choice = num if x == 0 & `hosp_id' == "Outside" qui replace `hosp_id'_chosen = "Outside" if x == 0 qui drop x * Save file * if "`save_inter'" == "" { qui tempfile choices_samp qui save "`choices_samp'" } else { qui save "`choices_samp'", replace } *timer off 3 *timer list 3 // Step 4: Estimate bins // *timer on 4 if "`ungrouped'" == "keep" { quietly gen all = 1 local bin_var = "all `groups'" } else { local bin_var = "`groups'" } local bin_num = wordcount("`bin_var'")+1 qui keep id `hosp_id' `owner_id' `a_side' `b_side' obs_choice `bin_var' if "`save_inter'" == "" { qui tempfile tempdata qui save "`tempdata'" qui tempfile bindata qui save "`bindata'" } else { qui save "`tempdata'", replace qui save "`bindata'", replace } forvalues i = `bin_num'(-1)2{ qui use "`tempdata'", clear * Limit to those that were not binned previously if not resampling * if "`replacement'" == "" & `i' < `bin_num' { qui merge 1:1 id `hosp_id' using "`bindata'", keep(1 3) nogen qui gen bin_id0 = 0 qui egen bin_id_tot = rowtotal(bin_id*) qui keep if bin_id_tot == 0 drop bin_id0 bin_id_tot } * Create bin definition * qui tokenize "`bin_var'" qui local bin_var = trim(subinword("`bin_var'","``i''","",.)) *display("- Bin by: `bin_var'") if _N > 0 { * Create unique bin ID qui egen bin_id = group(`bin_var') qui drop if bin_id == . * Collapse over bins * qui collapse (sum) episodes = obs_choice, by(bin_id `bin_var' `hosp_id') fast qui egen bin_tot = total(episodes), by(bin_id) if `i' > 2 { qui drop if bin_tot <= `min_group_size' } } * Report statistics * if _N == 0 { display("- Grouping by: `bin_var'; no obs. used.") } else { quietly sum episodes display "- Grouping by: `bin_var'; " round(100*r(sum)/N,0.01) "% of obs. used." } if _N > 0 { * Generate bin shares * qui gen bin_share`i' = episodes/bin_tot qui bys bin_id: egen check = sum(bin_share`i') qui assert abs(1-check)< .001 * Reset Bin ID * qui rename bin_id bin_id`i' qui rename bin_tot bin_tot`i' * Merge back into data * qui keep `bin_var' `hosp_id' bin_share`i' bin_id`i' bin_tot`i' qui joinby `bin_var' `hosp_id' using "`bindata'", unmatched(both) update qui drop if _merge == 1 qui drop _merge if "`save_inter'" == "" { qui tempfile bindata qui save "`bindata'" } else { qui save "`bindata'", replace } } } * Combine into single bin variable * qui use "`bindata'", clear qui gen firm_probBin = . qui gen bin_id = . qui gen bin_no = . qui gen se_Bin = . qui gen bin_tot = . forvalues i = `bin_num'(-1)2 { capture sum bin_id`i' if _rc == 0 { qui local CONDITIONAL "firm_probBin == . & bin_share`i' != ." qui replace bin_id = bin_id`i' if `CONDITIONAL' qui replace bin_no = `i' if `CONDITIONAL' qui replace se_Bin = sqrt(bin_share`i' * (1-bin_share`i') / bin_tot`i') if `CONDITIONAL' qui replace bin_tot = bin_tot`i' if `CONDITIONAL' qui replace firm_probBin = bin_share`i' if `CONDITIONAL' } } * Drop unmatched bins (probabilities do not sum to 1) * qui bys id: egen check = sum(firm_probBin) qui keep if abs(1-check)< .001 qui drop check * Renew bin ID * qui rename bin_id bin_id_old qui egen bin_id = group(bin_id_old bin_no) *qui keep bin_id `hosp_id' `owner_id' firm_probBin bin_tot `a_side' `b_side' `groups' *qui duplicates drop // Currently patient X choice panel -- each customer belongs to a bin; add up "num" over bin_id // and hosp_id to get number of customers in each bin. Add up "firm_probBin" to get expcted number // of episodes for each firm within bin gen num = 1 collapse (sum) bin_tot=num episodes=firm_probBin (mean) firm_probBin, by(bin_id `hosp_id' `owner_id' `a_side' `b_side') fast if "`save_inter'" == "" { qui tempfile bindata_final qui save "`bindata_final'" } else { qui save "`bindata_final'", replace } *timer off 4 *timer list 4 } else { preserve display("- Input intermediate data from: `inter_input'") qui levelsof `hosp_id' if `a_side' == 1, local(a_side_firms) qui levelsof `hosp_id' if `b_side' == 1, local(b_side_firms) qui local bindata_final "`inter_input'" qui use "`bindata_final'", clear foreach x in "a" "b" { capture gen ``x'_side' = 0 foreach y of local `x'_side_firms { qui replace ``x'_side' = 1 if `hosp_id' == "`y'" } } } // Step 5: Estimate diversions // *timer on 5 * Identify system if allow_within == 1 if "`allow_within'" == "" { qui levelsof `owner_id' if `a_side' == 1, local(a_side_name) qui gen ref_comp_a = (`owner_id' == `a_side_name') qui levelsof `owner_id' if `b_side' == 1, local(b_side_name) qui gen ref_comp_b = (`owner_id' == `b_side_name') } else { qui gen ref_comp_a = `a_side' qui gen ref_comp_b = `b_side' } * Compute number diverted to each alternative facility within each bin foreach j in "a" "b" { * Compute share proportional diversion ratio qui gen divert_numerator_omit_`j' = episodes if ref_comp_`j' != 1 qui egen divert_denominator_omit_`j' = total(divert_numerator_omit_`j'), by(bin_id) qui gen bin_diversion_ratio_omit_`j' = divert_numerator_omit_`j' / divert_denominator_omit_`j' * Find number to divert (total number of episodes - total number at alternative facilities = number to be diverted from facility in question) if "`allow_within'" == "" { qui gen chose_alternative_to_`j' = episodes if ``j'_side' != 1 qui egen total_chose_alternative_to_`j' = total(chose_alternative_to_`j'), by(bin_id) } else { qui gen total_chose_alternative_to_`j' = divert_denominator_omit_`j' } qui gen diverted_from_omitted_`j' = bin_tot - total_chose_alternative_to_`j' * Calculate number diverted from facility in question to each alternative facility qui gen num_diverted_`j' = bin_diversion_ratio_omit_`j' * diverted_from_omitted_`j' } qui collapse (sum) num_diverted* episodes, by(`hosp_id' `owner_id' `a_side' `b_side') fast * Calcaulte overall diversion ratios foreach j in "a" "b" { qui egen diversion_ratio_omit_`j' = pc(num_diverted_`j') } * Calculate shares to include in output qui egen shares = pc(episodes) * Clean up results * order `hosp_id' `owner_id' shares diversion_ratio_omit_a diversion_ratio_omit_b episodes num_diverted_a num_diverted_b qui gen sortvar = `a_side' + `b_side' qui replace sortvar = -1 if `hosp_id' == "Outside" gsort -sortvar -`a_side' -`b_side' `owner_id' `hosp_id' * Display results * display("") display("{ul:Diversion Results:}") qui gen Hospital = `hosp_id' qui gen Owner = `owner_id' qui gen Shares = round(shares,0.01) qui gen Diversion_Exclude_A = round(diversion_ratio_omit_a,0.001) qui gen Diversion_Exclude_B = round(diversion_ratio_omit_b,0.001) list Hospital Owner Shares Diversion_Exclude_A Diversion_Exclude_B, nolabel sepby(Owner) table string(`disp_str') compress abbreviate(20) qui drop sortvar Hospital Owner Shares Diversion_Exclude_A Diversion_Exclude_B * Save results * if "`save_inter'" != "" | "`output'" != "" { foreach var of varlist shares diversion_ratio_omit_a diversion_ratio_omit_b { qui replace `var' = `var'/100 } qui save "`results'", replace } mkmat shares diversion_*, matrix(results) rownames(`hosp_id') return matrix results results // Step 6: Willingness-to-pay // if "`wtp'" != "" { qui use "`bindata_final'", clear qui gen counterfactual = 0 qui append using "`bindata_final'" * Assign pre- and post-merger ownership * qui replace counterfactual = 1 if counterfactual == . * Pre-merger ownership * gen entity = 0 qui levelsof `owner_id' if `a_side' == 1, local(a_side_name) foreach owner_a of local a_side_name { qui replace entity = 1 if `owner_id' == "`owner_a'" & counterfactual == 0 } qui levelsof `owner_id' if `b_side' == 1, local(b_side_name) foreach owner_b of local b_side_name { qui replace entity = 2 if `owner_id' == "`owner_b'" & counterfactual == 0 } /*qui replace entity = 1 if `a_side' == 1 & counterfactual == 0 qui replace entity = 2 if `b_side' == 1 & counterfactual == 0*/ * Post-merger ownership * qui replace `owner_id' = "MERGED ENTITY" if (`a_side' == 1 | `b_side' == 1) & counterfactual == 1 qui replace entity = 3 if (`a_side' == 1 | `b_side' == 1) & counterfactual == 1 qui collapse (sum) firm_prob=firm_probBin (mean) bin_tot, by(bin_id `owner_id' entity counterfactual) fast * Topcode firm probabilities * qui replace firm_prob = `topcode' if firm_prob > `topcode' & firm_prob < . * Calculate individual WTP qui gen wtp = bin_tot*log(1/(1 - firm_prob)) * Aggregate * gen episodes = firm_prob*bin_tot qui collapse (sum) episodes wtp_agg=wtp, by(`owner_id' entity counterfactual) fast qui gen wtp_per = wtp_agg/episodes * Compute for A-side and B-side qui matrix wtp_results = J(5,2,.) qui matrix colnames wtp_results = wtp episodes qui matrix rownames wtp_results = aside bside merge pctch_agg pctch_per local j = 1 foreach x in "wtp_agg" "episodes" { qui sum `x' if entity == 1 & counterfactual == 0 qui matrix wtp_results[1,`j'] = r(sum) qui sum `x' if entity == 2 & counterfactual == 0 qui matrix wtp_results[2,`j'] = r(sum) qui sum `x' if entity == 3 & counterfactual == 1 qui matrix wtp_results[3,`j'] = r(sum) local j = `j' + 1 } * Save results * if "`save_inter'" != "" { qui save "`wtp_raw'", replace } * Calculate percent change in WTP * /* Calculate firm weights for WTP-per-person calculation qui sum episodes if entity == 1 & counterfactual == 0 local num_a = r(sum) qui sum episodes if entity == 2 & counterfactual == 0 local num_b = r(sum) local weight = `num_a'/(`num_a' + `num_b')*/ local weight = wtp_results[1,2]/(wtp_results[1,2] + wtp_results[2,2]) qui matrix wtp_results[4,1] = 100*(wtp_results[3,1] - wtp_results[1,1] - wtp_results[2,1])/(wtp_results[1,1] + wtp_results[2,1]) qui matrix wtp_results[5,1] = 100*((wtp_results[3,1]/wtp_results[3,2]) - `weight'*(wtp_results[1,1]/wtp_results[1,2]) - (1-`weight')*(wtp_results[2,1]/wtp_results[2,2]))/(`weight'*(wtp_results[1,1]/wtp_results[1,2]) + (1-`weight')*(wtp_results[2,1]/wtp_results[2,2])) * Display results * display "" display "{ul:WTP Results:}" display "" display "Percent Change in aggregate WTP is: " wtp_results[4,1] "%" display "Percent Change in WTP-per-person is: " wtp_results[5,1] "%" * Save results * if "`save_inter'" != "" | "`output'" != "" { // Turn matrix into data // qui svmat wtp_results qui keep wtp_results* qui drop if wtp_results1 == . qui rename (wtp_results1 wtp_results2) (wtp_agg episodes) // Label // qui label var wtp_agg "Aggregate WTP" qui label var episodes "Episodes" qui gen var = "A-side" qui replace var = "B-side" if _n == 2 qui replace var = "Merged" if _n == 3 qui replace var = "Percent Change in Aggregate WTP" if _n == 4 qui replace var = "Percent Change in WTP-per-person" if _n == 5 qui order var wtp_agg episodes qui save "`wtp_results'", replace } return matrix wtp_results = wtp_results, copy } *timer off 5 *timer list 5 restore capture qui drop ref_firm* num end