Hi Folks:
I'm trying to visualize the RR (95% CI) stratified by three time periods (early, middle and late) comparing between two subsets of data including Detroit vs excluding Detroit.
I have tables. But they're very busy. Is it possible to create a plot as shown below using the data I posted in the code snippet? Help creating this paneled forest plots is greatly appreciated.
data ci;
input Phases $ Detroit $ Variables $ rr rr_l rr_u p_value;
cards;
early yes Var1 1.0524 1.00966 1.09695 0.0158
early yes Var2 0.84551 0.79209 0.90254 0.0001
early yes Var3 1.0543 1.03979 1.06902 0.0001
early yes Var4 0.86697 0.81497 0.9223 0.0001
early yes Var5 1.00921 0.98268 1.03646 0.5
early yes Var6 0.70181 0.58942 0.83561 0.0001
early yes Var7 1.30173 1.03098 1.64358 0.0267
middle yes Var1 1.04559 1.01123 1.08111 0.0089
middle yes Var2 0.85085 0.80236 0.90227 0.0001
middle yes Var3 1.047 1.02776 1.0666 0.0001
middle yes Var4 0.92206 0.8788 0.96745 0.0009
middle yes Var5 0.99772 0.97841 1.01741 0.8189
middle yes Var6 0.97695 0.84688 1.12701 0.7491
middle yes Var7 0.98328 0.85264 1.13394 0.8167
late yes Var1 1.04109 1.0112 1.07187 0.0067
late yes Var2 0.97512 0.93336 1.01875 0.2593
late yes Var3 1.00412 0.9892 1.01926 0.5906
late yes Var4 0.99671 0.95982 1.03503 0.8642
late yes Var5 0.98736 0.97207 1.00289 0.1102
late yes Var6 1.06743 0.93955 1.2127 0.3162
late yes Var7 0.81891 0.73103 0.91736 0.0006
early no Var1 0.99983 0.97043 1.03011 0.991
early no Var2 0.96015 0.90744 1.01592 0.158
early no Var3 1.03307 1.01981 1.0465 0.0001
early no Var4 0.90236 0.86039 0.94637 0.0001
early no Var5 0.9896 0.97165 1.00789 0.2633
early no Var6 1.09426 0.90321 1.32571 0.3575
early no Var7 1.05676 0.89367 1.24961 0.5186
middle no Var1 1.02193 0.99727 1.04721 0.0818
middle no Var2 0.93691 0.89514 0.98062 0.0051
middle no Var3 1.01948 1.00417 1.03503 0.0125
middle no Var4 0.94738 0.91323 0.9828 0.0039
middle no Var5 0.99374 0.98005 1.00763 0.3751
middle no Var6 1.21477 1.06634 1.38385 0.0034
middle no Var7 0.89446 0.80586 0.9928 0.0361
late no Var1 1.03753 1.00869 1.06718 0.0104
late no Var2 0.99744 0.95469 1.04211 0.9089
late no Var3 0.99716 0.98166 1.0129 0.7216
late no Var4 1.00295 0.96614 1.04116 0.8775
late no Var5 0.98597 0.97142 1.00075 0.0627
late no Var6 1.13068 0.9913 1.28964 0.0673
late no Var7 0.79133 0.7083 0.8841 0.0001
;
data ci;
infile cards expandtabs;
input Phases $ Detroit $ Variables $ rr rr_l rr_u p_value;
cards;
early yes Var1 1.0524 1.00966 1.09695 0.0158
early yes Var2 0.84551 0.79209 0.90254 0.0001
early yes Var3 1.0543 1.03979 1.06902 0.0001
early yes Var4 0.86697 0.81497 0.9223 0.0001
early yes Var5 1.00921 0.98268 1.03646 0.5
early yes Var6 0.70181 0.58942 0.83561 0.0001
early yes Var7 1.30173 1.03098 1.64358 0.0267
middle yes Var1 1.04559 1.01123 1.08111 0.0089
middle yes Var2 0.85085 0.80236 0.90227 0.0001
middle yes Var3 1.047 1.02776 1.0666 0.0001
middle yes Var4 0.92206 0.8788 0.96745 0.0009
middle yes Var5 0.99772 0.97841 1.01741 0.8189
middle yes Var6 0.97695 0.84688 1.12701 0.7491
middle yes Var7 0.98328 0.85264 1.13394 0.8167
late yes Var1 1.04109 1.0112 1.07187 0.0067
late yes Var2 0.97512 0.93336 1.01875 0.2593
late yes Var3 1.00412 0.9892 1.01926 0.5906
late yes Var4 0.99671 0.95982 1.03503 0.8642
late yes Var5 0.98736 0.97207 1.00289 0.1102
late yes Var6 1.06743 0.93955 1.2127 0.3162
late yes Var7 0.81891 0.73103 0.91736 0.0006
early no Var1 0.99983 0.97043 1.03011 0.991
early no Var2 0.96015 0.90744 1.01592 0.158
early no Var3 1.03307 1.01981 1.0465 0.0001
early no Var4 0.90236 0.86039 0.94637 0.0001
early no Var5 0.9896 0.97165 1.00789 0.2633
early no Var6 1.09426 0.90321 1.32571 0.3575
early no Var7 1.05676 0.89367 1.24961 0.5186
middle no Var1 1.02193 0.99727 1.04721 0.0818
middle no Var2 0.93691 0.89514 0.98062 0.0051
middle no Var3 1.01948 1.00417 1.03503 0.0125
middle no Var4 0.94738 0.91323 0.9828 0.0039
middle no Var5 0.99374 0.98005 1.00763 0.3751
middle no Var6 1.21477 1.06634 1.38385 0.0034
middle no Var7 0.89446 0.80586 0.9928 0.0361
late no Var1 1.03753 1.00869 1.06718 0.0104
late no Var2 0.99744 0.95469 1.04211 0.9089
late no Var3 0.99716 0.98166 1.0129 0.7216
late no Var4 1.00295 0.96614 1.04116 0.8775
late no Var5 0.98597 0.97142 1.00075 0.0627
late no Var6 1.13068 0.9913 1.28964 0.0673
late no Var7 0.79133 0.7083 0.8841 0.0001
;
proc format;
value $fmt
'yes'='Inclde Detroit'
'no' ='exclude Detroit';
run;
proc sgpanel data=ci noautolegend;
styleattrs datacontrastcolors=(yellow orange red);
panelby Detroit Variables/ layout=lattice onepanel novarname proportional
rowheaderpos=left noheaderborder colheaderpos=top spacing=4 ;
scatter x= Phases y=rr/ markerattrs=(symbol=diamondfilled) group=Phases;
highlow x=Phases low=rr_l high=rr_u/group=Phases;
refline 1/axis=y lineattrs=(pattern=dash);
colaxis label=' ' ;
rowaxis label=' ' values=(1.5 1 0.5) ;
format Detroit $fmt.;
run;
Hi Ksharp. Sorry for a delay.
Thank you very much for the solution.
The plot below is the result from R. This plot mixes all in one panel and value of y-axis is ascending. I want it descending like you did. Your SAS approach splits All-data vs excluding Detroit making comparison across row easier.
Ksharp, can you help modify your code to show 95% bars with small range and closer to 1 look more prominent. For example, the plot below shows the upper and lower confidence limit even for the Var 3 despite its tightness. Can this be done by putting Var 6 and Var7 on different scale? and Var1-Var5 on different scale?
OK. Here is.
data ci; infile cards expandtabs; input Phases $ Detroit $ Variables $ rr rr_l rr_u p_value; cards; early yes Var1 1.0524 1.00966 1.09695 0.0158 early yes Var2 0.84551 0.79209 0.90254 0.0001 early yes Var3 1.0543 1.03979 1.06902 0.0001 early yes Var4 0.86697 0.81497 0.9223 0.0001 early yes Var5 1.00921 0.98268 1.03646 0.5 early yes Var6 0.70181 0.58942 0.83561 0.0001 early yes Var7 1.30173 1.03098 1.64358 0.0267 middle yes Var1 1.04559 1.01123 1.08111 0.0089 middle yes Var2 0.85085 0.80236 0.90227 0.0001 middle yes Var3 1.047 1.02776 1.0666 0.0001 middle yes Var4 0.92206 0.8788 0.96745 0.0009 middle yes Var5 0.99772 0.97841 1.01741 0.8189 middle yes Var6 0.97695 0.84688 1.12701 0.7491 middle yes Var7 0.98328 0.85264 1.13394 0.8167 late yes Var1 1.04109 1.0112 1.07187 0.0067 late yes Var2 0.97512 0.93336 1.01875 0.2593 late yes Var3 1.00412 0.9892 1.01926 0.5906 late yes Var4 0.99671 0.95982 1.03503 0.8642 late yes Var5 0.98736 0.97207 1.00289 0.1102 late yes Var6 1.06743 0.93955 1.2127 0.3162 late yes Var7 0.81891 0.73103 0.91736 0.0006 early no Var1 0.99983 0.97043 1.03011 0.991 early no Var2 0.96015 0.90744 1.01592 0.158 early no Var3 1.03307 1.01981 1.0465 0.0001 early no Var4 0.90236 0.86039 0.94637 0.0001 early no Var5 0.9896 0.97165 1.00789 0.2633 early no Var6 1.09426 0.90321 1.32571 0.3575 early no Var7 1.05676 0.89367 1.24961 0.5186 middle no Var1 1.02193 0.99727 1.04721 0.0818 middle no Var2 0.93691 0.89514 0.98062 0.0051 middle no Var3 1.01948 1.00417 1.03503 0.0125 middle no Var4 0.94738 0.91323 0.9828 0.0039 middle no Var5 0.99374 0.98005 1.00763 0.3751 middle no Var6 1.21477 1.06634 1.38385 0.0034 middle no Var7 0.89446 0.80586 0.9928 0.0361 late no Var1 1.03753 1.00869 1.06718 0.0104 late no Var2 0.99744 0.95469 1.04211 0.9089 late no Var3 0.99716 0.98166 1.0129 0.7216 late no Var4 1.00295 0.96614 1.04116 0.8775 late no Var5 0.98597 0.97142 1.00075 0.0627 late no Var6 1.13068 0.9913 1.28964 0.0673 late no Var7 0.79133 0.7083 0.8841 0.0001 ; proc format; value $fmt 'yes'='Inclde Detroit' 'no' ='exclude Detroit'; run; proc sgpanel data=ci noautolegend; styleattrs datacontrastcolors=(yellow orange red); panelby Detroit Variables/ layout=lattice onepanel novarname proportional rowheaderpos=left noheaderborder colheaderpos=top spacing=4 uniscale=column ; scatter x= Phases y=rr/ markerattrs=(symbol=squarefilled) group=Phases yerrorlower=rr_l yerrorupper=rr_u ; refline 1/axis=y lineattrs=(pattern=dash); colaxis label=' ' ; rowaxis label=' ' ; format Detroit $fmt.; run;
Great! Thanks. I'm trying to bring bars closer.
Do you know how to keep decimals places to two consistent across the panels? Now, it ranges 1-3. keeping it to two or three is desirable.
proc format;
value $fmt
'yes'='All data'
'no' ='Detroit excluded';
run;
ods graphics / width=300px height=1000px;
proc sgpanel data=ci noautolegend;
styleattrs datacontrastcolors=(black red green);
panelby Detroit Variables/ layout=lattice onepanel novarname proportional
rowheaderpos=left noheaderborder colheaderpos=top spacing=4 uniscale=column ;
scatter x= Phases y=rr/ markerattrs=(symbol=squarefilled) group=Phases yerrorlower=rr_l yerrorupper=rr_u ;
refline 1/axis=y lineattrs=(pattern=dash);
colaxis label=' ' ;
rowaxis label=' ' ;
format Detroit $fmt.;
run;
OK. This one.
colaxis label=' ' offsetmax=0.4 offsetmin=0.4 ; rowaxis label=' ' valuesformat=F8.2 ; format Detroit $fmt.; run;
Did the trick. Presto. 'Variables' in the ci data has long name in actuality. Do you know how to cut them to two lines to label on the y-axis? Right now, it is cut. After this, I'll post the final SAS code for the users who may have same plotting problem.
ods graphics / width=350px height=600px;
proc sgpanel data=ci_data1 noautolegend;
styleattrs datacontrastcolors=(black red green);
panelby Daegu Variables/ layout=lattice onepanel novarname proportional
rowheaderpos=left noheaderborder colheaderpos=top spacing=2 uniscale=column;
scatter x= Phases y=rr/ markerattrs=(symbol=squarefilled) group=Phases yerrorlower=rr_l yerrorupper=rr_u ;
refline 1/axis=y lineattrs=(pattern=dash);
colaxis display=none label=' ' offsetmax=0.4 offsetmin=0.4 ;
rowaxis label=' ' valuesformat=F8.2 ;
format Detroit $fmt. variables $variables.;
run;
It's a spacing issue. You simply don't have enough space for the name in the graphic. There's an option to wrap the axis label using a split character and/or to rotate it to show different. I'd probably align it to the bottom (LABELPOS) and add in the split character. I'd suggest descriptive names using labels as well....
Sorry . I can't help you.
Post it at Graphic Forum
https://communities.sas.com/t5/Graphics-Programming/bd-p/sas_graph
@DanH_sas @GraphGuy maybe have answer .
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 16. Read more here about why you should contribute and what is in it for you!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Select SAS Training centers are offering in-person courses. View upcoming courses for: