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

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);
1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

@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
;;;;

View solution in original post

10 REPLIES 10
PaigeMiller
Diamond | Level 26

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.

--
Paige Miller
thewan
Quartz | Level 8

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.

 

PaigeMiller
Diamond | Level 26

Why can't you put DATA TIME; in the macro, and so the last two lines of code are

 

%let num=3;

%example(...

 

???

--
Paige Miller
thewan
Quartz | Level 8

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.

gamotte
Rhodochrosite | Level 12

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);
thewan
Quartz | Level 8

Thanks for the suggestions. I'm going to see if dim will work as a solution for my program.

Tom
Super User Tom
Super User

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.

thewan
Quartz | Level 8

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.

Tom
Super User Tom
Super User

@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
;;;;
thewan
Quartz | Level 8

Thank you again. I can work with this.

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
  • 10 replies
  • 663 views
  • 0 likes
  • 4 in conversation