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

Can we write output statement in a macro?

In below example i want the same output in macro as in normal sas code.

Please correct my macro code.

 

Example:

SAS code:

 

data Word;
Name_list="Ramya Ranjan Sahu";
do i=1 to countw(Name_list)+1;
Word=scan(Name_list,i);
if i=4 then Word="No More Words";
Output;
end;
run;

 

Output Table:

 

Name_List                 i    Word

Ramya Ranjan Sahu  1  Ramya

Ramya Ranjan Sahu  2  Ranjan

Ramya Ranjan Sahu  3  Sahu

Ramya Ranjan Sahu  4  No More Words

 

Using Macro Code:

 

%let i=1;
%let name_list = Ramya Ranjan Sahu;

%macro Name;
data word;
%do i = 1 %to %eval(%sysfunc(countw(&name_list))+1);
%let word=%scan(&name_list,&i);
%if &i=4 %then %do; Word="No More Words"; %end;
output;
%end;
format word $15.;
%run;
%mend;

 

%name;

 

Output Table:

 

Word

Blank

Blank

Blank

No More Words

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
ramya_sahu
Obsidian | Level 7

I got my answer. thanks a lot.

Below code is working fine.

 

options symbolgen mprint;
%macro Name(Name_List);
data word;
%do i = 1 %to %eval(%sysfunc(countw(&name_list))+1);
word=scan("&name_list",&i);
%if &i=%eval(%sysfunc(countw(&name_list))+1) %then %do; Word="No More Words";
%end;
output;
%end;
format word $15.;
%run;
%mend;

%name(Ramya Ranjan Sahu);

 

View solution in original post

15 REPLIES 15
Cynthia_sas
SAS Super FREQ

Hi:
I don't understand what you mean when you say "i want the same output in macro as in normal sas code" -- the SAS Macro processor is only generating SAS code. By the time your code gets to the compiler, there are NO & or % references left in it. Or, as I like to joke with my students "what happens in macro, stays in macro". (OK, maybe it's not that funny a joke.)

But the bottom line is that the macro processor is NOT causing anything to execute. I am not sure what you thought you were sending to the compiler, but If you turn on the MPRINT option, you can see exactly what did get sent.

final_program.png

 

If you are expecting a different result, then you'll need different logic. but since the logic of what you want to do isn't clear, you might need to explain. Some questions that are in my mind are:

-- are you only ever using this program with a value for &name_list that will ALWAYS be 3 names? What about names like

Cher? or

John Jacob Jingleheimer Smith? Or

Jacqueline Bouvier Kennedy Onassis? or

The Artist Formerly Known as Prince? or

Johannes Chrysostomus Wolfgangus Theophilus Mozart?

 

Some of those names are fewer than 3 names and some of those names are more than 3 levels.

 

-- why test for &1=4 instead of using a %DO %WHILE or %DO %UNTIL

--why do this in a macro program at all?

-- the %LET Statement creates a macro variable in the Global Symbol Table, NOT in your output table so you might need to consider a different statement there.

 

When working with Macro programs, it is useful to start with a working SAS program that does what you want and then work backward to a macro program that will generate the working SAS code.

cynthia

ramya_sahu
Obsidian | Level 7

Thanks for your reply.

 

i first wrote a simple sas code & its output table.

 

Then i tried to write the same in macro. After writing macro i called the macro variable. but the out put result is different from normal sas code which i written first. 

 

I know macro process wont execute anything. we need to call it always to execute. 🙂

 

 

Cynthia_sas
SAS Super FREQ

Not exactly what is happening. When you make a macro program, you are making a package of code that only writes SAS code. When the Macro program "executes" it executes BEFORE the compiler touches any data. So Macro program execution will not normally be able to "see" your data. The actual resolved code that the Macro program writes is the final program that is sent forward to the compiler. It is this RESOLVED code (without any macro references) that executes. So you need to be very clear that when you are calling or invoking a macro program, you are NOT interacting with any data in such as way that the MACRO program writes to the PDV. What is writing to the PDV in your program are the DATA, OUTPUT and assignment statements.

cynthia

Astounding
PROC Star

You can, but you have to visualize the resulting program to make sure it's something you want to do.  In this case, the generated SAS code looks like this:

 

data word;

output;

output;

output;

Word="No More Words";

output;

run;

 

That's probably not the result you are hoping for.

 

%let word= assigns a value to a macro variable &WORD, which has absolutely nothing to do with a SAS DATA step.  While you can fix the problem with a change to one statement, it will require understanding the relationship between macro language and SAS language for this to be useful to you.  Here is just one example of a change you could make.  First, add a LENGTH statement:

 

data word;

length word $ 15;

 

Then change the macro %let word= statement to a DATA step statement:

 

word = "%scan(&name_list, &i)";

 

Finally, turn on the proper option so you can see what the result is:

 

options MPRINT;

 

It would be incredibly rare for a macro language programmer to do this in real life.  There is likely a better way to achieve your goal.

nehalsanghvi
Pyrite | Level 9

This statement in your macro code is not the same as a data step statement:

 

%let word=%scan(&name_list,&i);

 

The above statement is assigning the value to a macro variable called 'word' which is not the same as the data step variable 'word'. Macro variables do not get saved out to datasets. You cannot simply add % signs to all your data step code and expect it to behave the same. That is simply not what macros are 🙂

 

These are the statements you need to change: 

 

%let name_list = %str(Ramya Ranjan Sahu);

 

word=scan("&name_list",&i);

 

run; /* there is no statement such as %run */

 

ramya_sahu
Obsidian | Level 7
Thanks sangvi. I m new to SAS. I m learning SAS macro now.
You can see the out put of my first SAS code.

Can you please write me a SAS macro code which will give the same output?
nehalsanghvi
Pyrite | Level 9

I gave you the statements you needed to change in your macro portion. But here's the whole code:

 

%let i=1;
%let name_list = %str(Ramya Ranjan Sahu);

options mprint;

%macro Name;
data word2;
%do i = 1 %to %eval(%sysfunc(countw(&name_list))+1);
	Word=scan("&name_list",&i);  /* write value to a data step variable */
	%if &i=4 %then %do;
		Word="No More Words";
	%end;
	output;
%end;
format word $15.;
run;
%mend;

%name;
ramya_sahu
Obsidian | Level 7

Thanks Sanghvi;

 

This code serving my purpose.

 

But, in below step

 

%if &i=4 %then %do;

can we write something which will automatically detect 4 (since here three words i write 4)?

 

Do you have any link which will be helpful to me where to use % & where not in macro?

 

 

ramya_sahu
Obsidian | Level 7

I got my answer. thanks a lot.

Below code is working fine.

 

options symbolgen mprint;
%macro Name(Name_List);
data word;
%do i = 1 %to %eval(%sysfunc(countw(&name_list))+1);
word=scan("&name_list",&i);
%if &i=%eval(%sysfunc(countw(&name_list))+1) %then %do; Word="No More Words";
%end;
output;
%end;
format word $15.;
%run;
%mend;

%name(Ramya Ranjan Sahu);

 

ballardw
Super User

Somewhat over complicated to date. Please consider:

%macro name(Name_list);
   data Word;
      length word $ 25;
      do i=1 to countw("&Name_list")+1;
         Word=scan("&Name_list",i);
         if i=4 then Word="No More Words";
         Output;
      end;
   run;
%mend;
%name(Ramya Ranjan Sahu);

Note that use of a parameter means that you can use the macro with a different list:

 

%Name( Singh Carram Marie John);

Also you  should specifiy the length of the longest expected single WORD. Otherwise you end up with a 200 character length variable which may waste space and potentially cause some interesting issues if you ever use the || concatenation operator.

ramya_sahu
Obsidian | Level 7

hi balard, this code is serving my purose.

 

but, i still confused how this code given me result? because you have not ussed %do loop. you used only simple do loop.

 

will macro work with simple do loop too?

 

Cynthia_sas
SAS Super FREQ

Hi:
Your question "will macro 'work' with simple do loop" implies to me that you think the macro program is doing all the work. It it not.

The macro program is simply generating the code that will be sent to the compiler.

If you run the program that was provided to you and turn on the MPRINT option, you will be able to see the code that goes forward to the compiler.

I made a few slight changes to the program so that the stop value for the loop is set based on the COUNTW value -- that way, you do not have to hardcode the count value to create the last obs.

 

  Here are some papers that may help: https://support.sas.com/resources/papers/proceedings13/120-2013.pdf and http://www2.sas.com/proceedings/sugi28/056-28.pdf .

 

Hope this helps.

cynthia

 

use_mprint.png

ramya_sahu
Obsidian | Level 7

Thanks cynthia for your explanation.

 

i have small query.

 

what is the diff. between %do loop & do loop.?

because i saw in some programs with % do loop & some with do loop.

ballardw
Super User

%do is the MACRO loop and generates code that executes after the macro processor passes off for execution. This kind of loop could be involved with generated many lines of code either within a data step, entire data steps or procedure calls for each value of the loop.

 

The DO loop manipulates data within a single datastep for data step variables.

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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
  • 15 replies
  • 12625 views
  • 3 likes
  • 5 in conversation