BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
James_Yu
Obsidian | Level 7

Hi, I would like to use SGPLOT to create multi graphs using By-variable statement

- My code is like that:

Proc sgplot data=database;

    by Symptom;

scatter x=VisitNum y=Mean / groupdisplay=cluster group= Treatment;

run;

- This is some of the graphs created:

 

Untitled.png

123.png

My question is how could I change the label in the y axis to the name of variable (in this case: Symp1S Symp2S instead of Mean).

Thanks in advance

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
JeffMeyers
Barite | Level 11

As far as I am aware there is not way to do what you're asking directly.  I would suggest instead writing a short macro loop to do what you're trying to do:

%macro loop;
   proc sql noprint;
       select distinct symptom,label into :vlist separated by '|',:llist separated by '|' from database;
   quit;

   %do i = 1 %to %sysfunc(countw(&vlist,|));
        proc sgplot data=database;   
             where symptom="%Qscan(%superq(vlist),&i,|)";
             scatter x=VisitNum y=Mean / groupdisplay=cluster group=Treatment;
             yaxis label="%qscan(%superq(llist),&i,|,m)";
        run;
    %end;
%mend;
%loop;

For the above code to work you would need to have another variable in your dataset, which I named label above, to contain a string you want the y-axis label to be.  If you are using output statements to make your long version of your dataset you can use the VLABEL function to grab the label from each variable automatically.

 

If you instead of a dataset where you have the variables in separate columns instead of rows, you can instead make your loop with a %let statement:

%macro loop;
   %let vlist=var1 var2 var3 var4;
   %do i = 1 %to %sysfunc(countw(&vlist,|));
        proc sgplot data=database;   
             scatter x=VisitNum y=%scan(&vlist,&i,|) / groupdisplay=cluster group=Treatment;
        run;
    %end;
%mend;
%loop;

This method would then use the labels from the variables themselves to be the y-axis label.

View solution in original post

9 REPLIES 9
JeffMeyers
Barite | Level 11

As far as I am aware there is not way to do what you're asking directly.  I would suggest instead writing a short macro loop to do what you're trying to do:

%macro loop;
   proc sql noprint;
       select distinct symptom,label into :vlist separated by '|',:llist separated by '|' from database;
   quit;

   %do i = 1 %to %sysfunc(countw(&vlist,|));
        proc sgplot data=database;   
             where symptom="%Qscan(%superq(vlist),&i,|)";
             scatter x=VisitNum y=Mean / groupdisplay=cluster group=Treatment;
             yaxis label="%qscan(%superq(llist),&i,|,m)";
        run;
    %end;
%mend;
%loop;

For the above code to work you would need to have another variable in your dataset, which I named label above, to contain a string you want the y-axis label to be.  If you are using output statements to make your long version of your dataset you can use the VLABEL function to grab the label from each variable automatically.

 

If you instead of a dataset where you have the variables in separate columns instead of rows, you can instead make your loop with a %let statement:

%macro loop;
   %let vlist=var1 var2 var3 var4;
   %do i = 1 %to %sysfunc(countw(&vlist,|));
        proc sgplot data=database;   
             scatter x=VisitNum y=%scan(&vlist,&i,|) / groupdisplay=cluster group=Treatment;
        run;
    %end;
%mend;
%loop;

This method would then use the labels from the variables themselves to be the y-axis label.

James_Yu
Obsidian | Level 7

Your solution is very helpful sir. It works without any trouble

May I ask for another favor.

Because I'm pretty new to SAS so macro loop does not seem quite familiar with me. So could you please provide more explanation to these line of code ?

 

proc sql noprint;
       select distinct symptom,label into :vlist separated by '|',:llist separated by '|' from database;
   quit;
As far as I understand, this line of code create 2 macro variables vlist and llist
So what do "%sysfunc(countw(&vlist,|))", "%Qscan(%superq(vlist),&i,|)" and "%qscan(%superq(llist),&i,|,m)" do in these line of codes?

 

%do i = 1 %to %sysfunc(countw(&vlist,|));
where symptom="%Qscan(%superq(vlist),&i,|)";
label="%qscan(%superq(llist),&i,|,m)";
Thanks in advance

 

JeffMeyers
Barite | Level 11
You are correct. The SQL code creates two macro variables that are lists of values delimited by the | (pipe) symbol. I typically choose this symbol because I don't see it used in strings super often.

The COUNTW function counts how many words there are given a certain delimiter and in this case I used the | symbol to count words by. So even if you have a label or something that is multiple actual words, it will only count by | symbols. The COUNTW function is really handy for making loops where the number of loops might change with your data. The %SYSFUNC portion is needed to make the function work in the macro language capacity.

The %QSCAN is like the regular SCAN function but for the macro language. The macro language will replace itself with its result prior to running the actual code. In this can replace the %qscan section with the string it resolves to. The scan function will pick the nth word in a string using a specific delimiter (again using the | pipe here). %qscan will tell it to treat the result as macro text and will ignore things like quotations in the string which can be very handy when you have labels or something with special characters or quotes.

The %SUPERQ function resolves the macro variable and tells the result as macro text again (this is typical of any macro function with the Q in it). This keeps it form reading possible commas or quotes again when it puts that resolved text into the %qscan function.

I hope this helps.
James_Yu
Obsidian | Level 7

Thanks a lot for your clear explanation.

James_Yu
Obsidian | Level 7

May I ask a bit more details about your solution sir.

In my situation, I would like to add one more string to the label and place it in the title of the graph 

So far, I just added a title statement into the code like that: 

%macro loop;
   proc sql noprint;
       select distinct symptom,label into :vlist separated by '|',:llist separated by '|' from database;
   quit;

   %do i = 1 %to %sysfunc(countw(&vlist,|));
        proc sgplot data=database;   
             where symptom="%Qscan(%superq(vlist),&i,|)";
             scatter x=VisitNum y=Mean / groupdisplay=cluster group=Treatment;
             yaxis label="%qscan(%superq(llist),&i,|,m)";
            TITLE "%qscan(%superq(llist),&i,|,m)";
        run;
    %end;
%mend;
%loop;

And it shows the label on the title.

So how could I join another string to the "%qscan(%superq(llist),&i,|,m)" function to achieve a title like "Symptom: ....(the label)..."

 

Thanks in advance 

JeffMeyers
Barite | Level 11
You can put whatever you need to within the TITLE quotes. The %qscan will replace itself with the label amongst any other text:

TITLE "Symptom: %qscan(%superq(llist),&i,|,m) and any other text you want";

Just make sure to use double quotes or the macro functions won't work.
GraphGuy
Meteorite | Level 14

How about using a left-justified title2, that "looks like" a yaxis label at the top of the yaxis? 

 

options nobyline;
title1 "Stock prices";
title2 justify=left "#byval(stock)";


proc sgplot data=sashelp.stocks;
by stock;
series x=date y=close;
yaxis display=(nolabel) /*label="#byval(stock)"*/;
xaxis display=(nolabel);
run;

 

yaxis_byval.png

GraphGuy
Meteorite | Level 14

If you want the axis label in the middle of the axis, you could use SAS/Graph gplot.

 

options nobyline;
title1 "Stock prices";
symbol1 value=none interpol=join;
axis1 label=(angle=90 "#byval(stock)");
axis2 label=none;
proc gplot data=sashelp.stocks;
by stock;
plot close*date / vaxis=axis1 haxis=axis2;
run;

vaxis_byval.png

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 9 replies
  • 5157 views
  • 8 likes
  • 4 in conversation