This is an example code that boils down a problem I'm facing in a larger code.
My program is set up so the user will input these values at the bottom:
1) %let num
2) Datalines in the time table (if needed)
3) Macro parameters in %example
I want to reduce user input burden by getting rid of the free-hanging %let num = 3 statement. The problem is that I can't run the macro without the data step, and the data step uses &num.
Any suggestions on this? Thank you.
%macro example(num=, time=, equal= );
%if &equal=0 %then %do;
data new;
set time;
array utime (&num) time1 - time#
do i = 1 to #
utime[i] = utime[i]; /*if unequal spaced looks, time is taken from dataset time*/
end;
drop i;
run;
%end;
%else %do;
data new;
array utime (&num) time1 - time#
do i = 1 to #
utime[i] = &time/# /*if equal spaced looks, time divided by num*/
end;
drop i;
run;
%end;
proc print; run;
%mend;
%let num = 3; /*input number of looks here. if unequally-spaced times, enter times in below data step*/
data time;
input time1 - time# /*need &num here*/
infile datalines stopover;
datalines;
24 40 60
;
run;
%example(num =&num, equal=0, time=60);
@thewan wrote:
Thank you, I like this solution. It gets rid of the &num problem that I'm dealing with.
I'll have to play around with it. There are data validation steps in the program as well. Times have to be in ascending order and greater than zero. And stopover made sure that if the number of looks is 3 then the user has to enter three different time points.
Can you instruct them to enter the number of time points first?
data time;
input num @;
do i=1 to num ;
input time @;
if time < lag(time) then put 'ERROR: time values out of order.';
output;
end;
datalines;
3 10 20 30
;;;;
I want to reduce user input burden by getting rid of the free-hanging %let num = 3 statement. The problem is that I can't run the macro without the data step, and the data step uses &num.
Could you explain more why you have to get rid of this statement? It seems like you are creating your own problem.
What about moving the %let num=3; to the first line of the program. Does that help/meet your needs? Then the user only has to hange the first line of the code and then execute it.
I want to make sure the user does not miss the statement (all user inputs will be at the bottom).
In the final program, there are three data sets that the user will need to fill out (if they choose the unequal times option), and more parameters in the %example statement.
Why can't you put DATA TIME; in the macro, and so the last two lines of code are
%let num=3;
%example(...
???
Thanks for taking a look at this!
I'm not sure I understand your suggestion. If I put a data step with datalines in the macro, it generates an error.
Hello,
I'm not sure it answers your question but you can use the colon to specify a list of variables
with the same prefix. You can also use the dim function to obtain the size of an array.
%macro example(time=, equal= );
data new;
set time;
%if &equal. ne 0 %then %do;
array utime time:;
do over utime;
utime=&time/dim(utime); /*if equal spaced looks, time divided by num*/
end;
%end;
run;
proc print; run;
%mend;
data time;
input time1 - time3;
infile datalines stopover;
datalines;
24 40 60
;
run;
%example(equal=0, time=60);
Thanks for the suggestions. I'm going to see if dim will work as a solution for my program.
You only show one line of data. Will the user ever enter more than one line of data? If NOT then just change your data step to:
data time;
input time @@;
datalines;
24 40 60
;
If the different rows are important then change the data step to include a row counter.
data time;
row+1;
infile datalines truncover ;
do until (missing(time));
input time @;
if not missing(time) then output;
end;
datalines;
24 40 60
12 14 16
;
You can always transform the data to multiple variables if you need it, or change the code to handle the data in this tall format instead.
Thank you, I like this solution. It gets rid of the &num problem that I'm dealing with.
I'll have to play around with it. There are data validation steps in the program as well. Times have to be in ascending order and greater than zero. And stopover made sure that if the number of looks is 3 then the user has to enter three different time points.
@thewan wrote:
Thank you, I like this solution. It gets rid of the &num problem that I'm dealing with.
I'll have to play around with it. There are data validation steps in the program as well. Times have to be in ascending order and greater than zero. And stopover made sure that if the number of looks is 3 then the user has to enter three different time points.
Can you instruct them to enter the number of time points first?
data time;
input num @;
do i=1 to num ;
input time @;
if time < lag(time) then put 'ERROR: time values out of order.';
output;
end;
datalines;
3 10 20 30
;;;;
Thank you again. I can work with this.
Available on demand!
Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.
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.