/* lasagna.ado Geoff Dougherty, geoffdougherty@gmail.com Creates lasagna plots as described by Swihart, Caffo et al (2010): https://www.ncbi.nlm.nih.gov/pmc/articles/PMC2937254/ */ program define lasagna version 12 syntax varlist(min=2 max=2) [if] [in] , over(varname) [ levels(integer 5) *] tokenize `varlist' preserve marksample touse keep if `touse'==1 local stopMarker=0 local j=0 * create a new uniquely named variable to hold ordered group numbers * can't use tempvar because varname needs to be passed to twoway while `stopMarker'==0 { * assemble a varname from random characters forval a = 1/32 { local b=runiformint(65,90) local newChar=char(0`b') local vString="`vString'`newChar'" } capture confirm variable `vString' if _rc { local stopMarker=1 } else { local j=`j'+1 * if we can't find a unique varname after 10 tries, error and exit. if `j'>10 { error 507 } } } gen `vString'=. qui levels `over', local(categories) local i = 0 foreach c of local categories { local i = `i'+1 qui replace `vString'=`i' if `over'=="`c'" local ylab `ylab' `i' `" "`c'" "' } label variable `vString' "`over'" twoway contour `1' `vString' `2' if `touse', heatmap levels(`levels') `options' /// ylabel(`ylab', angle(horizontal)) drop `vString' restore end