Hi,
I have written a code in base sas to extract all the words in a string/paragraph.
I want to create a macro for it. But I failed. Requesting help. Thanks
Below are the Codes which is successfully running and the macro code which is not. Please advise.
=======running=========================================
data test;
i = 1;
word = 'I am using scan and index function in sas together and I got successful';
do while (find(word,scan(word,i),'t')>0);
w = scan(word,i);
output;
i+1;
end;
keep w i;
run;
===============================================
==========Error==============================
%macro wordparsin(word);
data test;
i = 1;
/* word = 'I am using scan and index function in sas together and I got successful'; */
%do %while (%find(&word,%scan(&word,i),'t')>0);
w = %scan(&word,i);
output;
i+1;
%end;
keep w i;
run;
%mend;
%wordparsin(I am using scan and index function in sas together);
========================================
As a tip, you can use countw() function for you loop and thus drop the other code:
data test; word = 'I am using scan and index function in sas together and I got successful'; do i=1 to countw(word); w=scan(word,i); output; end; keep w i; run;
And for your macro, just replace the word= line and pop macro text around it (though I don't see much point in the code).
The macro processor is a tool to write dynamic code, not for working with data.
The macro statements will work while the code is fetched, not while procedures or data steps are running.
Only a few of the data step functions have a macro-style equivalent.
Let's take a look at the log (see Maxim 2):
24 %macro wordparsin(word); 25 data test; 26 i = 1; 27 /* word = 'I am using scan and index function in sas together and I got successful'; */ 28 %do %while (%find(&word,%scan(&word,i),'t')>0); 29 w = %scan(&word,i); 30 output; 31 i+1; 32 %end; 33 keep w i; 34 run; 35 %mend; 36 37 %wordparsin(I am using scan and index function in sas together); WARNING: Apparent invocation of macro FIND not resolved. ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: i ERROR: Argument 2 to macro function %SCAN is not a number. ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: %find(&word,%scan(&word,i),'t')>0 ERROR: The condition in the %DO %WHILE loop, %find(&word,%scan(&word,i),'t')>0, yielded an invalid or missing value, . The macro will stop executing. ERROR: The macro WORDPARSIN will stop executing. 38 39 GOPTIONS NOACCESSIBLE; 40 %LET _CLIENTTASKLABEL=; 41 %LET _CLIENTPROJECTPATH=; 42 %LET _CLIENTPROJECTNAME=; 43 %LET _SASPROGRAMFILE=; 44 45 ;*';*";*/;quit;run; ____ 180 ERROR 180-322: Statement is not valid or it is used out of proper order. NOTE: The SAS System stopped processing this step because of errors. WARNING: The data set WORK.TEST may be incomplete. When this step was stopped there were 0 observations and 1 variables. NOTE: DATA statement used (Total process time): real time 0.03 seconds cpu time 0.00 seconds
The first WARNING alerts you to the fact that there is no %find macro function.
The first ERROR comes from the fact that the missing %find function produce some character value
The next ERROR from the %scan function comes from the fact that the macro processor finds the TEXT(!) i, which is not a number; note that variable i will only exist once the data step runs, not while the macro PREprocessor executes the macro.
And so on.
Keep your data step logic, and only make the input (the string) variable by replacing it with the macro parameter:
%macro wordparsin(word);
data test;
i = 1;
word = "&word";
do while (find(word,scan(word,i),'t')>0);
w = scan(word,i);
output;
i+1;
end;
keep w i;
run;
%mend;
%wordparsin(I am using scan and index function in sas together);
Thanks Kurt,
This is detaied explanation... and got to understand things very clearly...
As a tip, you can use countw() function for you loop and thus drop the other code:
data test; word = 'I am using scan and index function in sas together and I got successful'; do i=1 to countw(word); w=scan(word,i); output; end; keep w i; run;
And for your macro, just replace the word= line and pop macro text around it (though I don't see much point in the code).
You may want to parse a long string into its words, in a macro, then the code
would be similar to @RW9 code:
%macro parse(string);
%do i = 1 %to %sysfunc(countw(&staring));
%let word = %scan(&string,i);
%put I=&i WORD=&word;
%end;
%mend;
%parse(what wonderful world); /* try it */
Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!
What’s the difference between SAS Enterprise Guide and SAS Studio? How are they similar? Just ask SAS’ Danny Modlin.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.