DATA Step, Macro, Functions and more

writing a macro with 4 parameters

Reply
Occasional Contributor nrb
Occasional Contributor
Posts: 11

writing a macro with 4 parameters

Suppose we want to create several copies of a data set, but every time shuffled randomly.   This task can be done with the following SAS program.

 

Data new; set old; index=RANUNI(seed);

Run;

Proc sort data=new;

By index;

Run;

Data new; set new; drop index; run;

 

How can we write a macro program with 4 parameters: input, nsets, seed, and output. “input” is the name of the existing data set, “nsets” is the number of randomly shuffled data sets, “seed” is an integer‐valued seed for RANUNI(), and “output” is the prefix of the names of randomly shuffled data sets.

Super User
Posts: 17,842

Re: writing a macro with 4 parameters

Here's a good walk through in converting working code to a macro. 

 

If you follow the steps it's a straight forward process for your requirements. In fact I think the example in here is your other question....

 

http://www2.sas.com/proceedings/sugi28/056-28.pdf

Occasional Contributor nrb
Occasional Contributor
Posts: 11

Re: writing a macro with 4 parameters

So i'm converting the SAS code into a macro code? Can't I just replace the variables in the SAS code with the variables presented for the macro code?

Super User
Posts: 17,842

Re: writing a macro with 4 parameters

As a starter, yes, for full points, no. 

Your macro needs to generate multiple data sets, which you won't get by just changing variable names. You need to create a loop or split the dataset somehow. 

 

 “input” is the name of the existing data set,

“nsets” is the number of randomly shuffled data sets,

“seed” is an integer‐valued seed for RANUNI(),

 “output” is the prefix of the names of randomly shuffled data sets.

 

Out of curiousity, is this an undergrad, MBA, or grad school level course? 

Occasional Contributor nrb
Occasional Contributor
Posts: 11

Re: writing a macro with 4 parameters

grad school level, but i'm in undergrad taking it. 

Occasional Contributor nrb
Occasional Contributor
Posts: 11

What would happen in this code?

let's say I have the code below 

 

data cork;

input tree$1-3 north east south west;

datalines; 

T1 72 66 76 77

 T2 60 53 66 63

 T3 56 57 64 58

 T4 41 29 36 38

run;

 

The question is Then, suppose you submit the following code.

%RandomOrder(cork, 5, 0, outData)

 

what would happen in we printed this out?

Proc print data=outData1;  

Run; Proc print data=outData2;  

 

The problem i'm having is that i'm putting the %RandomOrder(cork, 5, 0, outData) below the run statement in the code presented above however it mentions "Statement is not valid or it is used out of proper order"

 

Here's the full question

Dataset contains 5 variables: tree, north, east, south, west. Read this data file into SAS. Suppose this SAS dataset name is ‘cork’. Then, suppose you submit the following code. %RandomOrder(cork, 5, 0, outData) Report the output of the following code: Proc print data=outData1;  Run; Proc print data=outData2;  Run;

Super User
Posts: 17,842

Re: What would happen in this code?

Without knowing what's in the macro RandomOrder we can't answer your question. 

 

 

Trusted Advisor
Posts: 1,385

Re: What would happen in this code?

RUN; statemant should close each PROC or data step;

 

Your code should be like:

Proc print data=outData1;  

Run;

 

Proc print data=outData2;  

run; 

Super User
Posts: 17,842

Re: What would happen in this code?

@Shmuel Although correct, that would leave the process hanging, not generate an error. 

Super User
Super User
Posts: 7,407

Re: What would happen in this code?

This is the third topic on exactly the same subject.  Please collect your questions and provide one post, with example test data in the form of a datastep, what the required output should be, and why.  Various examples have been provided to you, and the advice given has not been taken on board:

 

Super User
Posts: 6,946

Re: What would happen in this code?

I merged two threads; if there's another about this topic, notify me, so I can also merge it in here.

To the original poster: keep your posts about a topic in one thread, or helping you will become increasingly harder.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Super User
Super User
Posts: 7,407

Re: What would happen in this code?

To note, as per previous posts I have made here, your code is very sloppy, and hence you are getting problems:

data cork;

input tree$1-3 north east south west;

datalines; 

T1 72 66 76 77

 T2 60 53 66 63

 T3 56 57 64 58

 T4 41 29 36 38    <--- Where is the semicolon to finish this?  It may not be entirely necessary, but its bad coding!

run;

 

The question is Then, suppose you submit the following code.

%RandomOrder(cork, 5, 0, outData)       <--- again, where is the semicolon to finish this line, this looks like the cause of your issue as this line runs into the next.

 

what would happen in we printed this out?

Proc print data=outData1;      

Run; Proc print data=outData2;   <-- Why is this on the same line as the run; from the previous code, are you trying to hide code?

 

You can also make sure the macro itself exists at the time its called, i.e. somewhre before the call off %RandomOrder(), you need to have defined the macro with %macro RandomOrder;

 

Of course, also bear in mind the other advice given here in that the process itself isnt good, don't duplicate data just to have a different sort - its wastes disk space and is inefficient coding.  Assign flag variables which can then be used in sorts.

Occasional Contributor nrb
Occasional Contributor
Posts: 11

Write a macro program with 4 parameters

This is what I have tried to code but it's still incorrect and I need help leading towards the right direction

 

data cork;

input Tree$1-2 North South East West;

datalines;

T1 72 66 76 77

T2 60 53 66 63

T3 56 57 64 58

T4 41 29 36 38

T5 32 32 35 36

T6 30 35 34 26

%MACRO randomorder (input= ,nsets=, seed=, output=);

PROC SORT DATA = input OUT = "&output";

seed=ranuni(seed);

run;

%MEND select;

%randomorder(input=cork ,nsets=5, seed=0, output=outdata1)

 

The question is asking 

Suppose we want to create several copies of a data set, but every time shuffled randomly.   This task can be done with the following SAS program.

Data new;

set old;

index=RANUNI(seed);

Run;

Proc sort data=new;

By index;

Run;

Data new;

set new;

drop index;

run;

(a) Write a macro program with 4 parameters: input, nsets, seed, and output. “input” is the name of the existing data set, “nsets” is the number of randomly shuffled data sets, “seed” is an integer‐valued seed for RANUNI(), and “output” is the prefix of the names of randomly shuffled data sets.

B. Read the datalines It contains 5 variables: tree, north, east, south, west. Read this data file into SAS. Suppose this SAS dataset name is ‘cork’. Then, suppose you submit the following code. %RandomOrder(cork, 5, 0, outData). Report the output of the following code: Proc print data=outData1;  Run;

Super User
Posts: 6,946

Re: Write a macro program with 4 parameters

Before embarking on "macro-izing" code, you must make sure that the code is correct on its own.

PROC SORT DATA = input OUT = "&output";
seed=ranuni(seed);
run;

is not correct, as you can't set variables inside proc sort, and the sort misses the necessary by statement.

ie

proc sort
  data=sashelp.class
  out=class
;
seed = ranuni(seed);
run;

renders this log:

16         proc sort
17           data=sashelp.class
18           out=class
19         ;
20         seed = ranuni(seed);
           ____
           180
ERROR 180-322: Statement is not valid or it is used out of proper order.
21         run;
---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Super User
Posts: 5,085

Re: Write a macro program with 4 parameters

Here's a push in the right direction.

 

You posted the program you are aiming to replace with a macro.  You have to make sure the macro generates the same program.  For example, you need to begin by having the macro generate the equivalent of:

 

Data new;

set old;

index=RANUNI(seed);

Run;

 

To begin the macro, the code within would need to see something like this:

 

Data &output;

set &input;

index=RANUNI(&seed);

Run;

 

Each time a macro variable appears, it would get replaced by the value passed to that parameter when the macro is called. 

 

 

Ask a Question
Discussion stats
  • 16 replies
  • 351 views
  • 0 likes
  • 7 in conversation