DATA Step, Macro, Functions and more

Need answer if you can

Accepted Solution Solved
Reply
Occasional Contributor
Posts: 15
Accepted Solution

Need answer if you can

I need a macro with 3 positional parameters. one is string, one is delimter and one is word number. If word number is larger than the no of words in the string, a log message has to be printed that word number is out of bounds.

call:  %test(there is a question, %str( ),1)

Result: there is a question

call : %xscan(there is a question, %str( ),-2)

Result: a question


Accepted Solutions
Solution
‎11-13-2013 02:38 AM
Trusted Advisor
Posts: 1,137

Re: Need answer if you can

Please try the below macro,

/*positional parameters:*/

/*var=string*/

/*num=number of the word*/

/*del=delimiter*/

%macro test(var,num,del);

data _null_;

    %let count=%sysfunc(countw(&var));

    %let str=%sysfunc(scan("&var",&num,&del));

    %if &count >= &num %then %do;

    word=scan("&var",&num,&del);

    %put &str;

    %end;

    %else %do;

    %put "word number is out of bounds";

    %end;

run;

proc print;

run;

%mend;

%test(%str(ram rahul rohit),3," ")

Thanks,

Jagadish

Thanks,
Jag

View solution in original post


All Replies
Solution
‎11-13-2013 02:38 AM
Trusted Advisor
Posts: 1,137

Re: Need answer if you can

Please try the below macro,

/*positional parameters:*/

/*var=string*/

/*num=number of the word*/

/*del=delimiter*/

%macro test(var,num,del);

data _null_;

    %let count=%sysfunc(countw(&var));

    %let str=%sysfunc(scan("&var",&num,&del));

    %if &count >= &num %then %do;

    word=scan("&var",&num,&del);

    %put &str;

    %end;

    %else %do;

    %put "word number is out of bounds";

    %end;

run;

proc print;

run;

%mend;

%test(%str(ram rahul rohit),3," ")

Thanks,

Jagadish

Thanks,
Jag
Occasional Contributor
Posts: 15

Re: Need answer if you can

Posted in reply to Jagadishkatam

Thank You so much Jagadish. I'm in the process of learning Macros. This is giving the correct answer to me.

Occasional Contributor
Posts: 15

Re: Need answer if you can

Posted in reply to Jagadishkatam

Now I've one more scenario. Just need to change the above code.

Call:  %let sub_str = %test(this one is for learning, %str( ), -2);

          %put The value of sub_str = &sub_str;

Result: The value of sub_str = for learning

Super Contributor
Posts: 282

Re: Need answer if you can

Hi,

How about:

%macro tail(string,n,dlm);

  %let result_scan=%scan(&string,&n,&dlm);

  %if %length(&result_scan) %then

  %do;

    %let result_indexw=%sysfunc(indexw(&string,&result_scan,&dlm));

    %let result=%substr(&string,&result_indexw);

    %put &result;

  %end;

  %else

    %put Word number is out of bounds;

%mend tail;

%tail(one two three four five,2,%str( ));

%tail(one two three four five,-2,%str( ));

%tail(one two three four five,222,%str( ));

giving:

two three four five

four five

Word number is out of bounds

Regards,

Amir.

Occasional Contributor
Posts: 15

Re: Need answer if you can

Amir,

Thanks for your reply. Great effort. This one is also very helpful. Thanks again.

Occasional Contributor
Posts: 15

Re: Need answer if you can

Now I've one more scenario. Just need to change the above code.

Call:  %let sub_str = %test(this one is for learning, %str( ), -2);

          %put The value of sub_str = &sub_str;

Result: The value of sub_str = for learning

Super User
Super User
Posts: 7,039

Re: Need answer if you can

What do want as the result with &POS is out of range? What about when &POS=0?

What do want when delimiter is NOT space?

What about multiple adjacent delimiters?

One way to do this is to build the result into a variable and the expand the variable as the result of the macro call.

Here is an example. I leave it as an exercise to see what it does with multiple adjacent delimiters and how you could change that.

%macro test(str,dlm,pos);

%local i n top result ;

%let n=%sysfunc(countw(&str,&dlm));

%if &pos < 0 %then %let top=-1 ;

%else %let top=&n;

%if &pos=0 or &pos > &n or &pos < -&n %then %let result=Out of Bounds ;

%else %do i=&pos %to &top;

  %if &i>&pos %then %let result=&result.&dlm;

  %let result=&result.%qscan(&str,&i,&dlm);

%end;

&result.

%mend test;

277  %let sub_str = "%test(this one is for learning, %str( ), -2)";

278  %put The value of sub_str = &sub_str;

The value of sub_str = "for learning"

279  %let sub_str = "%test(this one|is|for learning,|, -2)";

280  %put The value of sub_str = &sub_str;

The value of sub_str = "is|for learning"

281  %let sub_str = "%test(this one|is|for learning,|, 22)";

282  %put The value of sub_str = &sub_str;

The value of sub_str = "Out of Bounds"

Occasional Contributor
Posts: 15

Re: Need answer if you can

Thank You so much Tom. This is really helpful for me as I'm in the learning process of Macros. Thanks for your time and really appreciate your response.

🔒 This topic is solved and locked.

Need further help from the community? Please ask a new question.

Discussion stats
  • 8 replies
  • 340 views
  • 7 likes
  • 4 in conversation