Data visualization with SAS programming

how to apply by group processing to sganno

Accepted Solution Solved
Reply
Frequent Contributor
Posts: 75
Accepted Solution

how to apply by group processing to sganno

[ Edited ]

Similar to what was apparently possible with SAS GCHART (https://v8doc.sas.com/sashtml/gref/bychap.htm), I would like to customize the annotation for the output from each BY group by incuding the BY variable in the sganno data set.

 

For example, in the following chart, I would only like to show the Female line in the Female chart and the Male line in the Male chart ... 

 

data Line;
  infile datalines dlm='#';
  length id $ 1
			label $ 27
         textcolor $ 9
         linecolor $ 9
		y1space $ 9
		y2space $ 9;

  input id $ function $ x1 y1 label $ x2 y2 textcolor linecolor y1space $ y2space $;
datalines;
F  # text # 50 # 63 # F Average 61 Inches # . # . # blue #  # datavalue # datavalue #
F # line # 10 # 61 #   # 99 # 61 #   # blue # datavalue # datavalue #
M # text # 20 # 66 # M Average 64 Inches # . # . # blue # # datavalue # datavalue #
M # line # 10 # 64 #   # 99 # 64 #   # blue # datavalue # datavalue #
;
run;
proc sort data=sashelp.class out=class;
by sex;
run;
proc sgplot data=class sganno=Line;
by sex;
 scatter x=weight y=height;
 yaxis min=55 max=75;
run;

ByAnno.png

 

Note this is my current workaround (macro processing with a do loop), however it would be great to know if this possible by using the BY statement.

/*See: http://support.sas.com/kb/26/155.html*/
/*http://blogs.sas.com/content/publishing/2015/01/30/sas-authors-tip-getting-the-macro-language-to-perform-a-do-loop-over-a-list-of-values/*/
proc sql noprint;
  select distinct sex into : sex_list separated by ' ' from class;
quit;
%macro plotBy(values);    
                                                                                                                
     /* Count the number of values in the string */                                                                                                                                   
     %let count=%sysfunc(countw(&values)); 

     /* Loop through the total number of values */                                                                                         
     %do i = 1 %to &count;                                                                                                              
      %let value=%qscan(&values,&i,%str( ));                                                                                            
        
		   proc sgplot data=class(where=(sex="&value")) sganno=Line(where=(id="&value"));
	 scatter x=weight y=height;
	 yaxis min=55 max=75;
	run;
 
     %end;                                                                                                                              
                                                                                                                                        
%mend; 
%plotBy(&sex_list); 

 

 

Many thanks,

Marie


Accepted Solutions
Solution
‎11-01-2016 10:00 PM
SAS Super FREQ
Posts: 1,081

Re: how to apply by group processing to sganno

[ Edited ]

When you are using SGPLOT, often you can get stuff done with statements and may not need annotate.  In this case, you can add the mean values to the original data set by 'Sex' and then use a reference line statement to get the result.  You can add additional data to the data set and display the text you need.  Using statement overlays is more robust, as such reference line values are sent to the axis for proper scaling.  Annotated values are not.

 

SGPlot annotation does not have BY variable support.  The need has not come up due to its different architecture.  However, if the need arises, we can add that feature in a future release.

 

data class;
  set sashelp.class end=last;
  output;

  if last then do;
    call missing (name, sex, age, height, weight);
    sex='M'; Avg=64; output;
    sex='F'; Avg=61; output;
  end;
run;

 

proc sort data=class out=class2;
by sex;
run;

 

proc sgplot data=class2 uniform=yscale;
  by sex;
  scatter x=weight y=height;
  refline avg / label;
run;

 

ScatterRefBySex.png

 

View solution in original post


All Replies
Solution
‎11-01-2016 10:00 PM
SAS Super FREQ
Posts: 1,081

Re: how to apply by group processing to sganno

[ Edited ]

When you are using SGPLOT, often you can get stuff done with statements and may not need annotate.  In this case, you can add the mean values to the original data set by 'Sex' and then use a reference line statement to get the result.  You can add additional data to the data set and display the text you need.  Using statement overlays is more robust, as such reference line values are sent to the axis for proper scaling.  Annotated values are not.

 

SGPlot annotation does not have BY variable support.  The need has not come up due to its different architecture.  However, if the need arises, we can add that feature in a future release.

 

data class;
  set sashelp.class end=last;
  output;

  if last then do;
    call missing (name, sex, age, height, weight);
    sex='M'; Avg=64; output;
    sex='F'; Avg=61; output;
  end;
run;

 

proc sort data=class out=class2;
by sex;
run;

 

proc sgplot data=class2 uniform=yscale;
  by sex;
  scatter x=weight y=height;
  refline avg / label;
run;

 

ScatterRefBySex.png

 

Frequent Contributor
Posts: 75

Re: how to apply by group processing to sganno

Thank-you for your comprehensive reply.  That SGPlot annotation does not have BY variable support answers my question.  I hadn't thought of the solution you provided but not sure if it would apply to my "real" problem.  The example I gave was fabricated and not what I am working on.  In my case, I am doing something similar to: vbar = Australian State (e.g.  QLD, NSW ...), the BY variable is operation type (e.g. hip replacement, ...) and the refline is national average (i.e., not the "by" variable, or state, average).  Also, I haven't hardcoded the national averages, but taking them from dataset itself.   

SAS Super FREQ
Posts: 1,081

Re: how to apply by group processing to sganno

I used hard coded values for convenience to suggest how to use SGPLOT for such a graph.  Clearly, one should use something like PROC MEANS and merge the data.  I beleive you will be able to use the "layered" SGPLOT approach for your real use case.  However, using GPLOT with the annotation is perfectly fine too.  

SAS Super FREQ
Posts: 1,081

Re: how to apply by group processing to sganno

Frequent Contributor
Posts: 75

Re: how to apply by group processing to sganno

Nice - confirming that your solution works for the real use case as well! Thanks again.
SAS Super FREQ
Posts: 1,081

Re: how to apply by group processing to sganno

If the average line is a national average, not part of the BY variable, it is likely straightforward.  You could compute the average into a macro variable and use that with the REFLINE statement.

☑ This topic is SOLVED.

Need further help from the community? Please ask a new question.

Discussion stats
  • 6 replies
  • 773 views
  • 1 like
  • 2 in conversation