Help using Base SAS procedures

Sysfunc and transwrd

Reply
N/A
Posts: 0

Sysfunc and transwrd

Hi,

I have a string of variables stored in macro variable &Ind_variable.

say

%let Ind_variable = x1 x2 x3;

I want to get new string of

x1, (n, mean, var) x2, (n, mean, var) x3, (n, mean, var)

to a new macro variable


I tried running this code but it does not work.

%let ind = %sysfunc(tranwrd(&ind_var, ' ', %str(', (n,mean,var)')));


Would be great if you could suggest something that would work here.

Thanks,

L
Super Contributor
Super Contributor
Posts: 3,174

Re: Sysfunc and transwrd

For what you're doing there are no tick-marks, just using %STR(). I suggest you change the logic to parse each variable and perform the TRANWRD on each sub-field - can be done in a macro logic form....

However, it may be easier to code, when performing in a DATA step instead - less %SYSFUNC activity. Then when complete, use CALL SYMPUT to stow the macro variable.

Scott Barry
SBBWorks, Inc.
Regular Contributor
Posts: 241

Re: Sysfunc and transwrd

It you don't have many, an one-liner will do. Or you can loop over with another quick macro. hth.
[pre]
%macro nmv(x);&x, (n, mean, var)%mend nmv;

%macro foreach(in=, do=, indlm=%str( ), outdlm=%str( ));
%local i item;
%let i = 1;
%let item = %scan(&in, &i, &indlm);
%do %while (&item ^=);
%*;%unquote(&do)
%let i = %eval(&i + 1);
%let item = %scan(&in, &i, &indlm);
%if &item ^= %then %*;&outdlm;
%end;
%mend foreach;

%put ***%nmv(x1) %nmv(x2)***;
%put ***%foreach(in=a b c, do=%nrstr(%nmv(&item)))***;
%*-- on log
***x1, (n, mean, var) x2, (n, mean, var)***
***a, (n, mean, var) b, (n, mean, var) c, (n, mean, var)***
--*;
[/pre]
Regular Contributor
Posts: 171

Re: Sysfunc and transwrd

Chang,

What does %*; do? The sequence appears twice in your solution. I can't remember seeing this before, so I'm just curious.

Thanks.
Regular Contributor
Posts: 241

Re: Sysfunc and transwrd

@polingjw: [pre] %*;[/pre] is just a macro comment statement, of course; without any comments, though. I am using it to remove leading blanks. Run my code without it, then you will see. You can do the same thing with some other ways like:
[pre] ...
%do %while (&item ^=)
;%unquote(&do)
%let i = %eval(&i + 1);
...[/pre]
or
[pre] ...
%do %while (&item ^=);
%do;%unquote(&do)%end;
%let i = %eval(&i + 1);
...[/pre]
but I think the null comment statement is simpler. hth.
Regular Contributor
Posts: 171

Re: Sysfunc and transwrd

Ok, now I see. Without the %*; sequence, the tab which precedes the %unquote is passed to the input stack.

Thanks! Message was edited by: polingjw
Contributor
Posts: 22

Re: Sysfunc and transwrd

For an alternative method of not returning excessive blanks etc see my macro posted above - yes it uses insignificantly more resources but is significantly easier for humans to read and understand and maintain and explain - a significant goal in development.
SAS Super FREQ
Posts: 8,743

Re: Sysfunc and transwrd

Hi:
There's always more than one way to accomplish a task like this. In addition to the 2 excellent suggestions already posted, another method (without using %SYSFUNC or using a macro program would use something like this:
[pre]
%let Ind_variable = x1 x2 x3;

** could put this in a %DO loop inside a macro program;
%let newx1 = %scan(&ind_variable,1),%str(%(n, mean, var%));
%put &newx1;

%let newx2 = %scan(&ind_variable,2),%str(%(n, mean, var%));
%put &newx2;

%let newx3 = %scan(&ind_variable,3),%str(%(n, mean, var%));
%put &newx3;

%let Ind_variable = &newx1 &newx2 &newx3;
%put &ind_variable;
** end of transform for 3 variables;
[/pre]

If you had an undetermined number of Xn variables in &IND_VARIABLE, then you could put a %DO loop in a macro program. The approach you use really depends on the rest of the code you're trying to generate.

cynthia
Contributor
Posts: 24

Re: Sysfunc and transwrd

%macro trans(v=);

%let y=;
%let i=1;
%do %while(%scan(&v,&i) ne);
%let y=&y %scan(&v,&i),(n, mean, var);
%let i=%eval(&i+1);
%end;

%put &y;
%put &v;
%mend;

%trans(v=x1 x2 x3);
Contributor
Posts: 22

Re: Sysfunc and transwrd

Here's a macro I use for such things:

/*******************************************************************************
* Name: lisuffix (List Item Suffix) *
* Desc: Returns a list with the specified suffix appended to each item. *
* Type: Macro Function - List *
* Usage: %lisuffix ( list , suffix ) *
* Where: list is a space delimited list *
* suffix is any string of characters *
* Examples: *
* 1) %let fylist=1996 1997 1998; *
* %let newlist=%lisuffix(&fylist,%str(,)); *
* %put ===> newlist=&newlist; *
* ===> newlist=1996,1997,1998, *
* 2) %let datelist=01JAN1999 01FEB1999 01MAR1999; *
* %let newlist=%liprefix(&datelist,%bquote(')); *
* %let newlist=%lisuffix(%bquote(&newlist),%bquote('d)); *
* %put ===> newlist=&newlist; *
* ===> '01JAN1999'd '01FEB1999'd '01MAR1999'd *
* History: *
* 3/15/00 Walt Smith - development *
*******************************************************************************/
%macro lisuffix (_list,_suff) /
des = 'Fn: Suffix each item in list with string'
;
%local return i signal wrd delim;
%let delim=%str( );
%let i=0;
%let signal=CONTINUE;
%do %until(&signal=DONE);
%let i=%eval(&i +1);
%let wrd=%qscan(&_list,&i,%str(&delim));
%if %length(&wrd)=0 %then
%let signal=DONE;
%else
%let return = &return.%str(&wrd)%str(&_suff)%str(&delim);
%end;
%unquote(&return)
%mend;


You need to be aware of macro quoting - if what you want to append to each item in your original list contains anything that is meaningful in calling a macro (like = signs, commas, etc) then just quote the whole thing. In your case, as I read your question you want to add ', (n, mean, var)' to each of x1 x2 x3:

%let ind_variable = x1 x2 x3;
%let newstr = %lisuffix( &ind_variable, %bquote(, (n, mean, var)) );
%put newstr = "&newstr";

result:
newstr = "x1, (n, mean, var) x2, (n, mean, var) x3, (n, mean, var)"

ouch! I just previewed this post and they filter out all whitespace so the macro looks pretty ugly - sorry ...
SAS Super FREQ
Posts: 8,743

Re: Sysfunc and transwrd

Hi:
This previous forum posting discusses how to preserve indenting and how to use characters like < and > in your code:
http://support.sas.com/forums/thread.jspa?messageID=27609毙

Basically, you use the [pre] and [/pre] tags around your code and output in order to maintain indenting and spacing. (This means that folks who want to cut and paste your code will have to cut and paste from the forum window into Microsoft Word or some other editor that respects carriage control/line feed and then cut and paste from -that- editor into the SAS window.)

cynthia
N/A
Posts: 0

Re: Sysfunc and transwrd

Thank you all for the excellent comments. I finally figured it Smiley Happy
Contributor
Posts: 22

Re: Sysfunc and transwrd

Sorry for my ignorance - and for any interested, here's the macro:

[pre]
/*******************************************************************************
* Name: lisuffix (List Item Suffix) *
* Desc: Returns a list with the specified suffix appended to each item. *
* Type: Macro Function - List *
* Usage: %lisuffix ( list , suffix ) *
* Where: list is a space delimited list *
* suffix is any string of characters *
* Examples: *
* 1) %let fylist=1996 1997 1998; *
* %let newlist=%lisuffix(&fylist,%str(,)); *
* %put ===> newlist=&newlist; *
* ===> newlist=1996,1997,1998, *
* 2) %let datelist=01JAN1999 01FEB1999 01MAR1999; *
* %let newlist=%liprefix(&datelist,%bquote(')); *
* %let newlist=%lisuffix(%bquote(&newlist),%bquote('d)); *
* %put ===> newlist=&newlist; *
* ===> '01JAN1999'd '01FEB1999'd '01MAR1999'd *
* History: *
* 3/15/00 Walt Smith - development *
*******************************************************************************/
%macro lisuffix (_list,_suff) /
des = 'Fn: Suffix each item in list with string'
;
%local return i signal wrd delim;
%let delim=%str( );
%let i=0;
%let signal=CONTINUE;
%do %until(&signal=DONE);
%let i=%eval(&i +1);
%let wrd=%qscan(&_list,&i,%str(&delim));
%if %length(&wrd)=0 %then
%let signal=DONE;
%else
%let return = &return.%str(&wrd)%str(&_suff)%str(&delim);
%end;
%unquote(&return)
%mend;
[/pre]
Super User
Posts: 9,687

Re: Sysfunc and transwrd

First of all, I am also confused.
But I think '&ind_var' is a macro variable,So must use macro itself type to translate;

[pre]
options symbolgen mprint mlogic;
%let ind_var =%str(x1 x2 x3 );
%let ind = %sysfunc(tranwrd(&ind_var.,%str( ),%str(,(n,mean,var) ) ));
%put &ind.;
[/pre]


Ksharp

Message was edited by: Ksharp
Ask a Question
Discussion stats
  • 13 replies
  • 414 views
  • 0 likes
  • 8 in conversation