Data visualization with SAS programming

Using a Macro to Create Multiple Plots of Variables (showing individual trends for each over time)

Reply
Occasional Contributor
Posts: 8

Using a Macro to Create Multiple Plots of Variables (showing individual trends for each over time)

Hi.

 

Is there a way to create a whole series of individual time series plots utilizing a macro (for all my independent variables, i.e. '&indvar') over a series of years (C_EDDYR)? (each plot would represent each individual '&indvar' by year)

 

I was able to get my trend test to work with the macro variable (see below):

 

proc freq data=t;

   tables C_EDDYR*(&indvar) / trend;

   where gastro_isol=0;

   run;

********************************************************

 ...but now, when I try various 'plotting codes' with the macro (to plot the trend I get statistics on above), I'm not able to get what I'm looking for:

 

/*try to plot time trend*/

 

  proc gplot data=t;

      plot C_EDDYR*(&indvar);

      symbol1 v=star c=blue;

      title "Time Series Plot for (&indvar) and Year of Estimated Delivery";

   where gastro_isol=0;

   run;

   quit;

   title;

 

   proc sgpanel data=t ;

  panelby (&indvar);

   series x=C_EDDYR y=(&indvar);

   where gastro_isol=0;  

run;

 

 

Any assistance would be greatly appreciated.

 

Thanks,

-Taylor (using SAS V 9.4)

Respected Advisor
Posts: 2,661

Re: Using a Macro to Create Multiple Plots of Variables (showing individual trends for each over tim

Posted in reply to Taylor081

So, you haven't written a macro, and you haven't given the macro variable &indvar a value.

 

But a macro isn't needed here. Nor is a macro variable needed here. Unless there are other complications you haven't told us about.

 

Use the search and replace option in the SAS editor to replace the string "&indvar" with the corresponding string of variables that you are interested in. Done. No macros. No macro variables.

--
Paige Miller
Occasional Contributor
Posts: 8

Re: Using a Macro to Create Multiple Plots of Variables (showing individual trends for each over tim

Posted in reply to PaigeMiller
Thanks.
Attaching the macro section below (I hesitated to initially include because there are so many variables involved). It would be great if the plots could incorporate the macro and create individual plots (one for each variable showing the time trend). Any other tips you may have would be greatly appreciated. Actually, is it even possible to plot the Cochran Armitage trend plots? (maybe there is no easy graphic for this)
Thanks.


data t;
set g2;
if HHIncGen inSmiley Sad1) then inc=0 ; /*less than 10,000*/
if HHIncSpec inSmiley Sad1) then inc=0 ; /*10,000 to 19,000*/
if HHIncSpec inSmiley Sad2) then inc=0 ; /*20,000 to 29,000*/
if HHIncSpec inSmiley Sad3) then inc=0 ; /*30,000 to 39,000*/
if HHIncSpec inSmiley Sad4) then inc=0 ; /*40,000 to 49,000*/
if HHIncGen inSmiley Sad2) then inc=1 ; /*50,000+*/

if HHIncSup inSmiley Sad0,1,2,3) then incs=0;
if HHIncSup ge 4 then incs=1;

if livebirths inSmiley Sad0) then lb=0;
if livebirths ge 1 then lb=1;

if Mlang inSmiley Sad8) then lang=0;/*english*/
if Mlang inSmiley Sad24) then lang=1; /*spanish*/

if c_meduc inSmiley Sad1,2) then educ_d=1;
if c_meduc inSmiley Sad3,4,5) then educ_d=0;


if C_bminih inSmiley Sad1,2) then bmid=0;
if C_bminih inSmiley Sad3,4) then bmid=1;

if **bleep**e_EDDyr lt 25 then **bleep**e=0;
if **bleep**e_EDDyr ge 25 and **bleep**e_EDDyr lt 35 then **bleep**e=0;
if **bleep**e_EDDyr ge 35 and **bleep**e_EDDyr lt 45 then **bleep**e=1;
if **bleep**e_EDDyr ge 45 then **bleep**e=1;

if C_mage_e lt 35 then mage=0;
if C_mage_e ge 35 then mage=1;

if C_binge4 inSmiley Sad0,2) then binge=0;
if C_binge4 inSmiley Sad1) then binge=1;

if MDS_qrtl inSmiley Sad0,1) then mds2=0;
if MDS_qrtl inSmiley Sad2,3) then mds2=1;

if DQI_qrtl inSmiley Sad0,1) then dqi2=0;
if DQI_qrtl inSmiley Sad2,3) then dqi2=1;

run;



%let indvar =
/*DQI_qrtl
MDS_qrtl */
mds2
/*GUI_B3P3 */
binge
tc
mage
C_mrace
C_frace
Crace
educ_d
Mborn
myrs
inc
incs
lang
C_smoke
work_or_home_B1P3
/*worksmk_B1P3*/
hsmkpg
homesmk_B1P3
lb
plurality
AnyOC
LocID
diab1_2
gestndiab_During2
HBP
HBPPg
bmid
hhinc
HH_dichot_median
**bleep**e
MMarij
mcocaine
mcrack
mhalluc
mhash
MHeroin
MMush
MJob
MAForces
Prenatal
Anyscan
Fertgate
Nausea
Heat_expB1P9
DrinkCook_1
seiz
solvent
/*pregnancy intention*/
int
/*residential moves B1P3*/
movingb1p3
injuryb1p3
GU_infectionb1p3
bronchodilatorb1p3
antiherpeticsb1p3
opioidb1p3
illicit_drugb1p3
short_IPI
/*fever from cold or flu B1P3*/
b1p3coldflu_fever
/*kidney, bladder, or UTI B3P9*/
KidBlUTI
pah_exp
mds2
dqi2
Inf_UTI_FevAny
homesmk_B1P3;




/*missings*/
%let missvar = if
(DQI_qrtl inSmiley Sad.) or
MDS_qrtl inSmiley Sad.) or
GUI_B3P3 inSmiley Sad.) or
C_binge4 inSmiley Sad.) or
tc inSmiley Sad.) or
/*no missings for C_mage_e*/
C_mrace inSmiley Sad.) or
C_frace inSmiley Sad.) or
Crace inSmiley Sad.) or
C_meduc inSmiley Sad.) or
Mborn inSmiley Sad.) or
myrs inSmiley Sad.) or
HHIncsup inSmiley Sad.) or
Mlang inSmiley Sad.) or
C_smoke inSmiley Sad.) or
work_or_home_B1P3 inSmiley Sad.) or
hsmkpg in(.) or

/*worksmk_B1P3*/
WsmkB1 inSmiley Sad.) or
WsmkM1 inSmiley Sad.) or
WsmkM2 inSmiley Sad.) or
WsmkM3 inSmiley Sad.) or

/*homesmk_B1P3*/
HsmkB1 inSmiley Sad.) or
HsmkM1 inSmiley Sad.) or
HsmkM2 inSmiley Sad.) or
HsmkM3 inSmiley Sad.) or


livebirths inSmiley Sad.) or
plurality inSmiley Sad.) or
AnyOC inSmiley Sad.) or

/*no missings for LocID*/

diab1_2 inSmiley Sad.) or
/*no missings for gestndiab_During2*/

HBP inSmiley Sad.) or
HBPPg inSmiley Sad.) or
C_bminih inSmiley Sad.) or
hhinc inSmiley Sad.) or
HH_dichot_median inSmiley Sad.) or

/*use **bleep**e for father's age*/
FBirthDD inSmiley Sad.) or
FBirthMM inSmiley Sad.) or
FBirthYY inSmiley Sad.) or

MMarij inSmiley Sad.) or
mcocaine inSmiley Sad.) or
mcrack inSmiley Sad.) or
mhalluc inSmiley Sad.) or
mhash inSmiley Sad.) or
MHeroin inSmiley Sad.) or
MMush inSmiley Sad.) or

MJob inSmiley Sad.) or
MAForces inSmiley Sad.) or
Prenatal inSmiley Sad.) or

Anyscan inSmiley Sad.) or
Fertgate inSmiley Sad.) or
Nausea inSmiley Sad.) or
Heat_expB1P9 in(.) or
DrinkCook_1 inSmiley Sad.) or
seiz inSmiley Sad.) or
solvent inSmiley Sad.) or
/*pregnancy intention*/
int inSmiley Sad.) or
/*residential moves B1P3*/
movingb1p3 inSmiley Sad.) or
injuryb1p3 inSmiley Sad.) or
GU_infectionb1p3 inSmiley Sad.) or
bronchodilatorb1p3 inSmiley Sad.) or
antiherpeticsb1p3 inSmiley Sad.) or
opioidb1p3 inSmiley Sad.) or
illicit_drugb1p3 inSmiley Sad.) or
short_IPI inSmiley Sad.) or
/*fever from cold or flu B1P3*/
b1p3coldflu_fever inSmiley Sad.) or
/*kidney, bladder, or UTI B3P9*/
KidBlUTI inSmiley Sad.) or
pah_exp inSmiley Sad.)) then delete;
run;


data i7;
set g2;
&missvar;
run;



/*Cochran Armitage Test for trend*/

proc freq data=t;
tables C_EDDYR*(&indvar) / trend;
where gastro_isol=0;
run;






/*try to plot time trend*/

proc gplot data=t;
plot C_EDDYR*(&indvar);
symbol1 v=star c=blue;
title "Time Series Plot for (&indvar) and Year of Estimated Delivery";
where gastro_isol=0;
run;
quit;
title;




proc sgpanel data=t ;
panelby (&indvar);
series x=C_EDDYR y=(&indvar);
where gastro_isol=0;
run;

Respected Advisor
Posts: 2,661

Re: Using a Macro to Create Multiple Plots of Variables (showing individual trends for each over tim

Posted in reply to Taylor081

Okay, I see now. Macros are usually used to create dynamic code, which can change depending on other pieces of data (for example, if the user requests the analysis for North America, you may have different variables than if the request is for Europe).

 

In your case, you seem to be using the macro variable to save some typing, certainly a valid use of macro variables (I do that sometimes too).

 

So, you need to turn on some options

 

options mprint mlogic symbolgen; 

and then run the code. I would need to see the SASLOG to determine what is the problem here.

--
Paige Miller
Occasional Contributor
Posts: 8

Re: Using a Macro to Create Multiple Plots of Variables (showing individual trends for each over tim

Posted in reply to PaigeMiller
Thanks. I included the options as suggestion.
Here are the errors in my log:

35651
35652
35653 /*try to plot time trend*/
35654 options mprint mlogic symbolgen;
35655
35656 proc gplot data=t;
35657 plot C_EDDYR*(&indvar);
SYMBOLGEN: Macro variable INDVAR resolves to mds2 binge tc mage C_mrace C_frace Crace educ_d
Mborn myrs inc incs lang C_smoke work_or_home_B1P3 hsmkpg homesmk_B1P3 lb
plurality AnyOC LocID diab1_2 gestndiab_During2 HBP HBPPg bmid hhinc
HH_dichot_median **bleep**e MMarij mcocaine mcrack mhalluc mhash MHeroin MMush MJob
MAForces Prenatal Anyscan Fertgate Nausea Heat_expB1P9 DrinkCook_1 seiz solvent
int movingb1p3 injuryb1p3 GU_infectionb1p3 bronchodilatorb1p3
antiherpeticsb1p3 opioidb1p3 illicit_drugb1p3 short_IPI b1p3coldflu_fever
KidBlUTI pah_exp mds2 dqi2 Inf_UTI_FevAny homesmk_B1P3
35658 symbol1 v=star c=blue;
SYMBOLGEN: Macro variable INDVAR resolves to mds2 binge tc mage C_mrace C_frace Crace educ_d
Mborn myrs inc incs lang C_smoke work_or_home_B1P3 hsmkpg homesmk_B1P3 lb
plurality AnyOC LocID diab1_2 gestndiab_During2 HBP HBPPg bmid hhinc
HH_dichot_median **bleep**e MMarij mcocaine mcrack mhalluc mhash MHeroin MMush MJob
MAForces Prenatal Anyscan Fertgate Nausea Heat_expB1P9 DrinkCook_1 seiz solvent
int movingb1p3 injuryb1p3 GU_infectionb1p3 bronchodilatorb1p3
antiherpeticsb1p3 opioidb1p3 illicit_drugb1p3 short_IPI b1p3coldflu_fever
KidBlUTI pah_exp mds2 dqi2 Inf_UTI_FevAny homesmk_B1P3
35659 title "Time Series Plot for (&indvar) and Year of Estimated Delivery";
NOTE: The quoted string currently being processed has become more than 262 characters long.
You might have unbalanced quotation marks.
35660 where gastro_isol=0;
35661 run;

WARNING: The text of TITLE is too long. It will be truncated.
WARNING: TITLE1 is too long. Height has been reduced to 34.74 pct of specified or default size.
NOTE: 634 observation(s) contained a MISSING value for the C_EDDYR * mds2 request.
NOTE: 398 observation(s) contained a MISSING value for the C_EDDYR * binge request.
NOTE: 325 observation(s) contained a MISSING value for the C_EDDYR * tc request.
NOTE: 7 observation(s) contained a MISSING value for the C_EDDYR * C_mrace request.
NOTE: 483 observation(s) contained a MISSING value for the C_EDDYR * C_frace request.
NOTE: 482 observation(s) contained a MISSING value for the C_EDDYR * crace request.
NOTE: 342 observation(s) contained a MISSING value for the C_EDDYR * educ_d request.
NOTE: 332 observation(s) contained a MISSING value for the C_EDDYR * MBorn request.
NOTE: 6 observation(s) contained a MISSING value for the C_EDDYR * myrs request.
NOTE: 1171 observation(s) contained a MISSING value for the C_EDDYR * inc request.
NOTE: 1108 observation(s) contained a MISSING value for the C_EDDYR * incs request.
NOTE: 800 observation(s) contained a MISSING value for the C_EDDYR * lang request.
NOTE: 298 observation(s) contained a MISSING value for the C_EDDYR * C_smoke request.
NOTE: 328 observation(s) contained a MISSING value for the C_EDDYR * work_or_home_B1P3 request.
NOTE: 296 observation(s) contained a MISSING value for the C_EDDYR * HSmkPg request.
NOTE: 303 observation(s) contained a MISSING value for the C_EDDYR * homesmk_B1P3 request.
NOTE: 51 observation(s) contained a MISSING value for the C_EDDYR * lb request.
NOTE: 1 observation(s) contained a MISSING value for the C_EDDYR * plurality request.
NOTE: 8368 observation(s) contained a MISSING value for the C_EDDYR * AnyOC request.
NOTE: 79 observation(s) contained a MISSING value for the C_EDDYR * diab1_2 request.
NOTE: 452 observation(s) contained a MISSING value for the C_EDDYR * gestndiab_During2 request.
NOTE: 75 observation(s) contained a MISSING value for the C_EDDYR * HBP request.
NOTE: 10132 observation(s) contained a MISSING value for the C_EDDYR * HBPPg request.
NOTE: 549 observation(s) contained a MISSING value for the C_EDDYR * bmid request.
NOTE: 1087 observation(s) contained a MISSING value for the C_EDDYR * hhinc request.
NOTE: 1404 observation(s) contained a MISSING value for the C_EDDYR * HH_dichot_median request.
NOTE: 310 observation(s) contained a MISSING value for the C_EDDYR * MMarij request.
NOTE: 308 observation(s) contained a MISSING value for the C_EDDYR * MCocaine request.
NOTE: 5096 observation(s) contained a MISSING value for the C_EDDYR * MCrack request.
NOTE: 5096 observation(s) contained a MISSING value for the C_EDDYR * MHalluc request.
NOTE: 5096 observation(s) contained a MISSING value for the C_EDDYR * MHash request.
NOTE: 5095 observation(s) contained a MISSING value for the C_EDDYR * MHeroin request.
NOTE: 5096 observation(s) contained a MISSING value for the C_EDDYR * MMush request.
NOTE: 315 observation(s) contained a MISSING value for the C_EDDYR * Mjob request.
NOTE: 326 observation(s) contained a MISSING value for the C_EDDYR * MAForces request.
NOTE: 144 observation(s) contained a MISSING value for the C_EDDYR * Prenatal request.
NOTE: 122 observation(s) contained a MISSING value for the C_EDDYR * AnyScan request.
NOTE: 265 observation(s) contained a MISSING value for the C_EDDYR * FertGate request.
NOTE: 72 observation(s) contained a MISSING value for the C_EDDYR * Nausea request.
NOTE: 5105 observation(s) contained a MISSING value for the C_EDDYR * Heat_expB1P9 request.
NOTE: 6248 observation(s) contained a MISSING value for the C_EDDYR * DrinkCook_1 request.
NOTE: 81 observation(s) contained a MISSING value for the C_EDDYR * Seiz request.
NOTE: 6983 observation(s) contained a MISSING value for the C_EDDYR * Solvent request.
NOTE: 58 observation(s) contained a MISSING value for the C_EDDYR * int request.
NOTE: 263 observation(s) contained a MISSING value for the C_EDDYR * movingb1p3 request.
NOTE: 103 observation(s) contained a MISSING value for the C_EDDYR * injuryb1p3 request.
NOTE: 256 observation(s) contained a MISSING value for the C_EDDYR * GU_infectionb1p3 request.
NOTE: 232 observation(s) contained a MISSING value for the C_EDDYR * bronchodilatorb1p3 request.
NOTE: 213 observation(s) contained a MISSING value for the C_EDDYR * antiherpeticsb1p3 request.
NOTE: 217 observation(s) contained a MISSING value for the C_EDDYR * opioidb1p3 request.
NOTE: 316 observation(s) contained a MISSING value for the C_EDDYR * illicit_drugb1p3 request.
NOTE: 3988 observation(s) contained a MISSING value for the C_EDDYR * short_IPI request.
NOTE: 7423 observation(s) contained a MISSING value for the C_EDDYR * b1p3coldflu_fever request.
NOTE: 117 observation(s) contained a MISSING value for the C_EDDYR * KidBlUTI request.
NOTE: 3664 observation(s) contained a MISSING value for the C_EDDYR * pah_exp request.
NOTE: 634 observation(s) contained a MISSING value for the C_EDDYR * mds2 request.
NOTE: 626 observation(s) contained a MISSING value for the C_EDDYR * dqi2 request.
NOTE: 9415 observation(s) contained a MISSING value for the C_EDDYR * INF_UTI_FevAny request.
NOTE: 303 observation(s) contained a MISSING value for the C_EDDYR * homesmk_B1P3 request.
35662 quit;

NOTE: There were 11724 observations read from the data set WORK.T.
WHERE gastro_isol=0;
NOTE: PROCEDURE GPLOT used (Total process time):
real time 15.29 seconds
cpu time 13.61 seconds


35663 title;
Respected Advisor
Posts: 2,661

Re: Using a Macro to Create Multiple Plots of Variables (showing individual trends for each over tim

Posted in reply to Taylor081

This is very frustrating, because nowhere have you actually ever stated what the problem is, other than you need help with macros. What is the problem you see when you run this code?

 

There is a warning about the title statement, is that the problem? Or something else?

--
Paige Miller
Occasional Contributor
Posts: 8

Re: Using a Macro to Create Multiple Plots of Variables (showing individual trends for each over tim

Posted in reply to PaigeMiller
Thanks. And my apologies for not being more clear. Let's reframe. Forget about the macro for now. Do you happen to know how I can graph?:

/*Cochran Armitage Test for trend*/

proc freq data=t;
tables var1*var2/ trend;
run;
Respected Advisor
Posts: 2,661

Re: Using a Macro to Create Multiple Plots of Variables (showing individual trends for each over tim

Posted in reply to Taylor081

This is very vague as well. The Cochran-Armitage test is a statistic, a single number, I don't understand the concept of plotting a single number.

--
Paige Miller
Occasional Contributor
Posts: 8

Re: Using a Macro to Create Multiple Plots of Variables (showing individual trends for each over tim

Posted in reply to PaigeMiller
Looks like you can do a sort of frequency plot (from: https://support.sas.com/documentation/cdl/en/procstat/63104/HTML/default/viewer.htm#procstat_freq_se...):

ods graphics on;
proc freq data=Pain;
tables Adverse*Dose / trend measures cl
plots=freqplot(twoway=stacked);
test smdrc;
exact trend / maxtime=60;
weight Count;
title 'Clinical Trial for Treatment of Pain';
run;
ods graphics off;

I don't want the 'twoway=stacked' though (which gives split bar charts). Is there a way to modify this to show a basic line chart with frequency changes over time?

Frequent Contributor
Posts: 108

Re: Using a Macro to Create Multiple Plots of Variables (showing individual trends for each over tim

Posted in reply to Taylor081
proc freq data=Pain;
   tables Adverse*Dose / trend measures cl
          plots=freqplot(twoway=stacked) out=freq_counts;
   test smdrc;
   exact trend / maxtime=60;
   weight Count;
   title 'Clinical Trial for Treatment of Pain';
run;

proc sgplot data=freq_counts;
  title 'Adverse By Dose';
  series x=dose y=count / group=adverse 
                          markers
                          markerattrs=(symbol=circlefilled)
                          datalabel;
run;

produces the line chart in the screen shot below.

 

Adverse reactions by dose.jpgLine plot of adverse reactions by dose

Ask a Question
Discussion stats
  • 9 replies
  • 158 views
  • 0 likes
  • 3 in conversation