BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
rmacarthur
Pyrite | Level 9

Hi SAS Friends, 

I've inherited the following code (test data and code below). 

It creates .GIF output that advances in integer units ( t_days = 1, 2, 3, 4, 5, 6).  However the source dataset  advance in units of 0.125 ( t_days = 0.125, 0.25. 0.375. 0.5...), and for the .GIF file to be accurate, need it to advance at those smaller intervals.

Any suggestions about how to amend this code to accommodate that?

/*****************************************************************/

data test;
input t_days	Cp_tot	Cp_tot_2;
cards;
t_days	Cp_tot	Cp_tot_2
0	0	0
0.125	12.829861994	25.659723989
0.25	19.108883486	38.217766972
0.375	21.46446787	42.928935739
0.5	43.097579093	86.195158186
0.625	40.779643827	81.559287653
0.75	37.235330034	74.470660067
0.875	33.220430967	66.440861935
1	50.722202305	101.44440461
1.125	45.724999478	91.449998956
1.25	40.443085571	80.886171143
1.375	35.301262254	70.602524507
1.5	52.072140167	104.14428033
1.625	46.60087866	93.20175732
1.75	41.011472329	82.022944658
1.875	35.670183328	71.340366657
2	52.311658727	104.62331745
2.125	46.756437678	93.512875356
2.25	41.112547745	82.225095491
2.375	35.735895659	71.471791318
2.5	52.354412259	104.70882452
2.625	46.784280561	93.568561122
2.75	41.130702594	82.261405187
2.875	35.747752218	71.495504436
3	52.362171222	104.72434244
3.125	46.789371147	93.578742293
3.25	41.134053396	82.268106793
3.375	35.749966908	71.499933816
3.5	52.363642522	104.72728504
3.625	46.790354788	93.580709575
3.75	41.134716103	82.269432205
3.875	35.750417544	71.500835087
4	52.363952313	104.72790463
4.125	46.790570449	93.581140898
4.25	41.134868374	82.269736748
4.375	35.750526732	71.501053464
4.5	52.364031902	104.7280638
4.625	46.790629446	93.581258893
4.75	41.134912843	82.269825686
4.875	35.750560792	71.501121584
5	52.364058381	104.72811676
5.125	46.790650311	93.581300621
5.25	41.134929479	82.269858958
5.375	35.750574192	71.501148384
5.5	52.364069267	104.72813853
5.625	46.790659217	93.581318434
5.75	41.134936807	82.269873615
5.875	35.75058025	71.501160501
6	52.364074294	104.72814859
;
run;

/* Create macro loop to run proc sgplot */


%macro Series(start=, end=, incr=);
  %do time=&start %to &end %by &incr;

proc sgplot data = Sample_2_con;
where t_days le &time;
title "C vs T";
series x = t_days y = Cp_tot;
series x = t_days y = Cp_tot_2;                       /* each image has two time series */
xaxis integer values = (0 to 7);
yaxis min = 0 max = 120 grid;                         /* set common axes */
run;

  %end;
%mend Series;

/* Create animation */

ods graphics / imagefmt=GIF width=4in height=3in;     /* each image is 4in x 3in GIF */
options papersize=('4 in', '3 in')                    /* set size for images */
        nodate nonumber                               /* do not show date, time, or frame number */
        animduration=0.5 animloop=yes noanimoverlay   /* animation details */
        printerpath=gif animation=start;              /* start recording images to GIF */
ods printer file='[INSERT PATH HERE]\An_1.gif';       /* images saved into animated GIF */
 
/* ods html select none; */                                 /* suppress screen output */

%Series(start=0, end=6, incr=1);

ods html select all;                                  /* restore screen output */
 
options printerpath=gif animation=stop;               /* stop recording images */
ods printer close;                                    /* close the animated GIF file */

Thank you very much!

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

Normal macro arithmetic is INTEGER only.

So just increment by 125 and then divide the result by 1000 to get steps of 0, 0.125, 0.25 , ... 6.000

%macro Series(start=, end=, incr=,divisor=1);
  %do time=&start %to &end %by &incr;

proc sgplot data = Sample_2_con;
  where t_days le &time/&divisor;
  title "C vs T";
/* each image has two time series */
  series x = t_days y = Cp_tot;
  series x = t_days y = Cp_tot_2; 
/* set common axes */
  xaxis integer values = (0 to 7);
  yaxis min = 0 max = 120 grid;
run;
  %end;
%mend Series;

... 

%Series(start=0, end=6000, incr=125, divisor=1000);

PS Place comments about code BEFORE the code so the person reading the code can SEE the comment before they read the code rather than wondering why the heck they coded it that way.

View solution in original post

6 REPLIES 6
Tom
Super User Tom
Super User

Normal macro arithmetic is INTEGER only.

So just increment by 125 and then divide the result by 1000 to get steps of 0, 0.125, 0.25 , ... 6.000

%macro Series(start=, end=, incr=,divisor=1);
  %do time=&start %to &end %by &incr;

proc sgplot data = Sample_2_con;
  where t_days le &time/&divisor;
  title "C vs T";
/* each image has two time series */
  series x = t_days y = Cp_tot;
  series x = t_days y = Cp_tot_2; 
/* set common axes */
  xaxis integer values = (0 to 7);
  yaxis min = 0 max = 120 grid;
run;
  %end;
%mend Series;

... 

%Series(start=0, end=6000, incr=125, divisor=1000);

PS Place comments about code BEFORE the code so the person reading the code can SEE the comment before they read the code rather than wondering why the heck they coded it that way.

rmacarthur
Pyrite | Level 9

Thank you very much, the code works properly now, which is great !. 

 

What I still do not understand is this line :
%do time=&start %to &end %by &incr;  

 

Is time a temporary variable of some kind? 

It does not appear in the PROC SGPlot  procedure, or in the source dataset.  But it controls how many images are produced by the PROC SGPlot procedure, for the .GIF file.

 

Thanks again!

 

 

Tom
Super User Tom
Super User

@rmacarthur wrote:

Thank you very much, the code works properly now, which is great !. 

 

What I still do not understand is this line :
%do time=&start %to &end %by &incr;  

 

Is time a temporary variable of some kind? 

It does not appear in the PROC SGPlot  procedure, or in the source dataset.  But it controls how many images are produced by the PROC SGPlot procedure, for the .GIF file.

 

Thanks again!

 

 


TIME is a MACRO VARIABLE.  

In this code it is use as the iterator variable for the macro %DO loop.

Inside the %DO loop it is used to generate part of this SAS statement:

  where t_days le &time/&divisor;

So when TIME has the value 1250 and DIVISOR has the value 1000 the following SAS statement is generated and run.

  where t_days le 1250/1000;

You should modify the definition of the macro %SERIES() to define TIME as a LOCAL macro variable.  That will prevent the %SERIES() macro from modify any existing macro variable named TIME that might be used by the program that is calling %SERIES().

%macro Series(start=, end=, incr=,divisor=1);
  %local time;
  %do time=&start %to &end %by &incr;

proc sgplot data = Sample_2_con;
  where t_days le &time/&divisor;
  title "C vs T";
/* each image has two time series */
  series x = t_days y = Cp_tot;
  series x = t_days y = Cp_tot_2; 
/* set common axes */
  xaxis integer values = (0 to 7);
  yaxis min = 0 max = 120 grid;
run;
  %end;
%mend Series;

Note that the parameters of the %SERIES() macro [ START, END, INCR and DIVISOR ] are all LOCAL macro variables also.

rmacarthur
Pyrite | Level 9

Thank you again !, makes much more sense now and have added the %local designation for the Time variable.  Robert

Ksharp
Super User
/*
Here is some code you could start with.
*/
%macro Series(start=, end=, incr=);
  %let time=&start. ;
  %do %while(%sysevalf(&time.<=&end.,boolean));
    %put &=time. ;
 %let time=%sysevalf(&time.+&incr.);
  %end;
%mend Series;

%Series(start=0, end=6, incr= 0.125)
TIME=0
TIME=0.125
TIME=0.25
TIME=0.375
TIME=0.5
TIME=0.625
TIME=0.75
TIME=0.875
TIME=1
TIME=1.125
TIME=1.25
TIME=1.375
TIME=1.5
TIME=1.625
TIME=1.75
TIME=1.875
TIME=2
TIME=2.125
TIME=2.25
TIME=2.375
TIME=2.5
TIME=2.625
TIME=2.75
TIME=2.875
TIME=3
TIME=3.125
TIME=3.25
TIME=3.375
TIME=3.5
TIME=3.625
TIME=3.75
TIME=3.875
TIME=4
TIME=4.125
TIME=4.25
TIME=4.375
TIME=4.5
TIME=4.625
TIME=4.75
TIME=4.875
TIME=5
TIME=5.125
TIME=5.25
TIME=5.375
TIME=5.5
TIME=5.625
TIME=5.75
TIME=5.875
TIME=6






rmacarthur
Pyrite | Level 9

Thank you very much, I am working with this code to better understand it and see how it also provides a solution.  Much appreciated, Robert 

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 6 replies
  • 988 views
  • 3 likes
  • 3 in conversation