####################################### Mirrored Histogram ####################################### *************** What's this? *************** Macro for Mirrored histogram using SAS GRAPH. Mirrored histogram shows the distribution of response variable two groups. Histogram of the group which level is 2 will be inverted. ***************** Input data ***************** Input data must be pre-summarized data. To summarize raw data, proc univariate is useful. required variable is described below. .. csv-table:: "**key**", "**variable** ", "**type**" "1","group","numeric" "2","level", "numeric" "","response", "numeric" group variable must be two level, 1 or 2. I recommended that format is applied to group variable. *************** Syntax *************** :: ods graphics / < graphics option > ; ods listing gpath=< output path >; %MirroredHist( data=, group=, x=, y=, xticks=None, yticks=, xaxistype=discrete, xlabel=x, ylabel=y, tickfmt=09.9, orient=v, legend=true, barwidth=1, outline=true, palette=sns, note=, deletedata=True ) *************** Parameters *************** - **data : dataset name (required)** input data. keep, rename and where options are available. - **group : variable name (required)** group variable. number of groups must be two. - **x : variable name (required)** level variable or midpoint of bins - **y : variable name (required)** response variable - **xticks : numeric list (optional)** tickvalue list of level axis. the list is set as the numeric list separated by space . the item of the list should be set ascending order. ex. xticks = 0.25 0.5 0.75 1, if this parameter is "none", tick list will be generated automatically. default is "none". - **yticks : numeric list (required)** tickvalue list of response axis. the list is set as the numeric list separated by space and numeric must be positive. if zero is not contained in the list, the macro will be insert "0" into the list. ex. yticks = 0.1 0.2 0.3, - **xaxistype : discrete or linear (optional)** axis type of level axis. if level variable is continuous, "linear" is recommended. defalut is "discrete". - **xlabel : string (optional)** label string of category axis. default is "x". when the label is not displayed , set like below. xlabel=, - **ylabel : string (optional)** optional. label string of response axis. default is "y". when the label is not displayed , set like below. ylabel=, - **ytickfmt : string (optional)** tick value format of response axis. this is picture format. for more detail, see SAS help of picture format. default is "09.9" (ticks will be displayed first decimal place). - **orient : v or h (optional)** Orientation of the plot (vertical or horizontal). default is "v". - **legend : bool (optional)** if "True" , legend of group item is displayed. default is "True". - **barwidth : numeric (0 to 1) (optional)** width of bar. if "1", no gaps between the bars. default is "1". - **outline : bool (optional)** display setting of bar outline. default is "True". - **palette : keyword (optional)** color palette for fill, line and markers. the palletes described below is available. see color palette section of introduction page. defalut is "SNS" (Seaborn defalut palette). * SAS * SNS (Seaborn) * STATA * TABLEAU - **note : statement (optional)** insert the text entry statement into the graph template and display the title or footnote in the output image. default is "" (not displayed) - **deletedata : bool (optional)** if True, the temporary datasets and catalogs generated by macros will be deleted at the end of execution. default is True. *************** example *************** .. highlight:: SAS output example can be executed using following code after loading SAS plotter. code :: ods listing gpath="your output path"; filename exam url "https://github.com/Superman-jp/SAS_Plotter/raw/main/example/mirrored_histogram_example.sas" encoding='UTF-8'; %include exam; vertical histogram ======================= raw data :: proc univariate data=sashelp.heart; var diastolic systolic; histogram diastolic systolic / outhistogram=histo vscale=percent noplot midpoints=50 to 400 by 5; run; proc format; value catf 1="Diastolic" 2="Systolic"; run; data graph_data; set histo; if _VAR_="Diastolic" then cat=1; if _VAR_="Systolic" then cat=2; format cat catf.; keep cat _midpt_ _obspct_; run; code :: title "vertical mirrored histogram"; ods graphics / height=15cm width=25cm imagefmt=png imagename="mirroredhist_v"; %MirroredHist( data=graph_data, group=cat, x=_midpt_, y=_obspct_, xaxistype=linear, xticks=50 100 150 200 250 300, yticks=5 10 15 20 25, xlabel=Blood pressure (mmHg), note=%nrstr(entrytitle 'your title here'; entryfootnote halign=left 'your footnote here'; entryfootnote halign=left 'your footnote here 2';) ); .. image:: ./img/mirroredhist_v1.svg when ytickfmt paramater is set "09.99", percent ticks will be displayed at second decimal place. The format generated by picture statement is available. code :: title "mirrored histogram with y-tick format"; ods graphics / height=15cm width=25cm imagefmt=png imagename="mirroredhist_v_fmt"; %MirroredHist( data=graph_data, group=cat, x=_midpt_, y=_obspct_, xaxistype=linear, ytickfmt=09.00, xticks=50 100 150 200 250 300, yticks=5 10 15 20 25 , xlabel=Blood pressure (mmHg) ); .. image:: ./img/mirroredhist_v_fmt1.svg horizontal histogram ======================= when orient parameter is set "h", histogram is displayed in horizontal Orientation.The plot is also called "Butterfly chart". (x: response, y=level) code :: title "horizontal mirrored histogram (linear)"; ods graphics / height=15cm width=25cm imagefmt=png imagename="mirroredhist_h_linear"; %MirroredHist( data=graph_data, group=cat, x=_midpt_, y=_obspct_, xaxistype=linear, xticks=50 100 150 200 250 300, yticks=5 10 15 20 25, orient=h, xlabel=Blood pressure (mmHg), note=%nrstr(entrytitle 'your title here'; entryfootnote halign=left 'your footnote here'; entryfootnote halign=left 'your footnote here 2';) ); .. image:: ./img/mirroredhist_h_linear1.svg if xaxistype parameter is "discrete" and orient parameter is "h", y-axis will be reversed. raw data :: proc format; value sexf 1="Male" 2="Female"; value agegrpf 1="<10" 2="10s" 3="20s" 4="30s" 5="40s" 6="50s" 7="60s" 8="70s" 9="80s" 10="90s" 11=">100" 99="unknown" ; run; data covid19_tokyo_2021; infile datalines delimiter=","; length sexc $10 agec $20 patients 8; format sex sexf. agegrp agegrpf.; input sexc $ agec $ patients; select (sexc); when ("Male") sex=1; when("Female")sex=2; end; select(agec); when("<10") agegrp=1; when("10s") agegrp=2; when("20s") agegrp=3; when("30s") agegrp=4; when("40s") agegrp=5; when("50s") agegrp=6; when("60s") agegrp=7; when("70s") agegrp=8; when("80s") agegrp=9; when("90s") agegrp=10; when(">100") agegrp=11; when("unknown")agegrp=99; end; datalines; Male,<10,8011 Male,10s,13821 Male,20s,49695 Male,30s,37503 Male,40s,30862 Male,50s,21952 Male,60s,8544 Male,70s,5202 Male,80s,2930 Male,90s,654 Male,>100,22 Male,unknown,4 Female,<10,7519 Female,10s,12359 Female,20s,43162 Female,30s,25594 Female,40s,20121 Female,50s,15931 Female,60s,6238 Female,70s,4872 Female,80s,4196 Female,90s,1765 Female,>100,116 ; run; code :: title "horizontal mirrored histogram (discrete)"; ods graphics / height=15cm width=25cm imagefmt=png imagename="mirroredhist_h_discrete"; %MirroredHist( data=covid19_tokyo_2021, group=sex, x=agegrp, y=patients, xaxistype=discrete, yticks=0 10000 20000 30000 40000 50000, ytickfmt=%str(00,009), xlabel=age, ylabel=number of patients, orient=h ); .. image:: ./img/mirroredhist_h_discrete1.svg