BookmarkSubscribeRSS Feed
deleted_user
Not applicable
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
13 REPLIES 13
sbb
Lapis Lazuli | Level 10 sbb
Lapis Lazuli | Level 10
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.
chang_y_chung_hotmail_com
Obsidian | Level 7
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]
polingjw
Quartz | Level 8
Chang,

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

Thanks.
chang_y_chung_hotmail_com
Obsidian | Level 7
@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.
polingjw
Quartz | Level 8
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
WaltSmith
Fluorite | Level 6
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.
Cynthia_sas
SAS Super FREQ
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
SUN59338
Obsidian | Level 7
%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);
WaltSmith
Fluorite | Level 6
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 ...
Cynthia_sas
SAS Super FREQ
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
deleted_user
Not applicable
Thank you all for the excellent comments. I finally figured it 🙂
WaltSmith
Fluorite | Level 6
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]
Ksharp
Super User
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

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!

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

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
  • 13 replies
  • 1562 views
  • 0 likes
  • 8 in conversation