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

%let name=AE,DM,ED,KK,OO,GG; * there could be n number of comma seprated values;

 

*result required;

String='AE','DM','ED','KK','OO','GG'

 

Note-we have to take care that name can have min one value or max 100 comma separated values.

 

If anyone have any resolution.Kindly help me on the same.

 

Regards

Ankit

1 ACCEPTED SOLUTION

Accepted Solutions
Quentin
Super User

Richard DeVenezia has a great function-style macro utility %seplist, which is used for management of lists in the macro language.  Given a list of items, it can add quotes, or add a prefix, or change the delimiter etc.  It's really handy.

 

https://www.devenezia.com/downloads/sas/macros/index.php?m=seplist

 

e.g.:

 

21   %let name=AE,DM,ED,KK,OO,GG;
22
23   %put %seplist(%superq(name),indlm=%str(,),nest=Q) ;
'AE','DM','ED','KK','OO','GG'
24   %put %seplist(%superq(name),indlm=%str(,),dlm=%str( )) ;
AE DM ED KK OO GG
25   %put %seplist(%superq(name),indlm=%str(,),prefix=_) ;
_AE,_DM,_ED,_KK,_OO,_GG

I changed the last line of the macro to definition to %unquote(&emit)  because sometimes the macro language doesn't handle unquoting properly. 

BASUG is hosting free webinars Next up: Mike Raithel presenting on validating data files on Wednesday July 17. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.

View solution in original post

11 REPLIES 11
Kurt_Bremser
Super User

I'd do it in a data step:

data _null_;
oldvar = "&name";
length newvar $1000;
do i = 1 to countw(oldvar,',');
  newvar = catx(',',newvar,"'"!!scan(oldvar,i,',')!!"'");
end;
call symput('newname',trim(newvar));
run;

or you use the quote() function:

data _null_;
oldvar = "&name";
length newvar $1000;
do i = 1 to countw(oldvar,',');
  newvar = catx(',',newvar,quote(scan(oldvar,i,','),"'"));
end;
call symput('newname',trim(newvar));
run;
RW9
Diamond | Level 26 RW9
Diamond | Level 26

I assume this is for a where clause of some kind?  If so you can do it there:

%let name=M,F; 

data want;
set sashelp.class;
where sex in ("%sysfunc(tranwrd(%quote(&name.),%str(,),%str(" ")))");
run;
andreas_lds
Jade | Level 19

Assuming that there is no whitespace in the value:

 

%let name=AE,DM,ED,KK,OO,GG;

data _null_;
   length newvar $ 1000;
   newvar = cats("'", tranwrd("&name.", ",", "','"), "'");
   call symputx('newname', newvar);
run;

%put &=name;
%put &=newname;

 

EDIT: i should have reloaded the tab firefox to see that @RW9 already posted a solution with tranwrd 😐

Quentin
Super User

Richard DeVenezia has a great function-style macro utility %seplist, which is used for management of lists in the macro language.  Given a list of items, it can add quotes, or add a prefix, or change the delimiter etc.  It's really handy.

 

https://www.devenezia.com/downloads/sas/macros/index.php?m=seplist

 

e.g.:

 

21   %let name=AE,DM,ED,KK,OO,GG;
22
23   %put %seplist(%superq(name),indlm=%str(,),nest=Q) ;
'AE','DM','ED','KK','OO','GG'
24   %put %seplist(%superq(name),indlm=%str(,),dlm=%str( )) ;
AE DM ED KK OO GG
25   %put %seplist(%superq(name),indlm=%str(,),prefix=_) ;
_AE,_DM,_ED,_KK,_OO,_GG

I changed the last line of the macro to definition to %unquote(&emit)  because sometimes the macro language doesn't handle unquoting properly. 

BASUG is hosting free webinars Next up: Mike Raithel presenting on validating data files on Wednesday July 17. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
novinosrin
Tourmaline | Level 20

@Quentin  Very nice sir. Thank you for sharing!

 

Would you mind posting similar stuff in our community library for the benefit of wider audience plz

Quentin
Super User

@novinosrin It's not my macro, Richard gets all the credit.  I don't think Richard is on communities.sas.com (?), but since he has it posted to his website, he's obviously happy to share.  I'm not likely to write up a post for the library any time soon.  But please, you should feel free. 

 

Or I know @ScottBass has shared a version of Richard's %seplist at https://github.com/scottbass/SAS/blob/master/Macro/seplist.sas.  Maybe Scott will write a library article on his whole macro library, including %seplist.

BASUG is hosting free webinars Next up: Mike Raithel presenting on validating data files on Wednesday July 17. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
ScottBass
Rhodochrosite | Level 12

Adding to @Quentin's comments...

 

I have a personal coding preference to never mix syntax in with my macro data.

 

For example, if my list is AE,DM,ED,KK,OO,GG, then I would always code it as:

 

 

%let list=AE DM ED KK OO GG;

 

and never:

 

 

%let list=AE,DM,ED,KK,OO,GG;

 

or

 

 

%let list='AE','DM','ED','KK','OO','GG';

 

The commas and quotes are syntax elements, not data.

 

For example, what if that list is a list of column names for a keep statement?  You only want a comma-separated, quoted list because you're going to use the list in a where clause IN() operator (???)  That's syntax, dictated by the context in which the macro variable is being referenced.

 

If my data contains spaces, I use a different delimiter that will not be in my data; either a caret (^), tilde (~), or pipe (|) will usually work.

 

For example:

 

 

%let list=Hello World ^ Billy Bob ^ Peggy Sue;

 

Then, I "inject" the correct syntax into the code at run time, when the data is referenced.

 

For example:

 

 

%let list=Hello World ^ Billy Bob ^ Peggy Sue;
%put %seplist(&list,nest=Q,indlm=^);


* Or a contrived example: ;


%let list=This Is My Directory Path;
%put %seplist(&list,dlm=/);


* Using my favourite %loop macro: ;


%let list=Hello World ~ Billy Bob ~ Peggy Sue; %macro code; %put &=word; %mend;
%loop(&list,dlm=~);
* or even: ; %macro code;
%if &__iter__ gt 1 %then ,;
"&word"
%mend;
%put %loop(&list,dlm=~);


* Which "works", but isn't as clean as %seplist for this use case. ;

* or for a "two-dimensional array": ;

%let list=FOO|BAR~BAR|BLAH~BAZ|BOO;
%macro code;
%let name=%scan(&word,1,|);
%let value=%scan(&word,2,|);
%put &name=&value;
%mend;
%loop(&list,dlm=~);

 

 (I don't know why the Rich Text editor is reformatting my SAS code, but I give up!)

 

Commas are particularly problematic in macro variables and require all sorts of quoting that is unnecessary.

 

See my GitHub repository for the %seplist, %loop, %loop_control, and %squote macros.  Make sure to read the use cases in the macro header.

 

BTW, I haven't used &&&macrovar&i syntax in years...

 

Hope this helps...

 


Please post your question as a self-contained data step in the form of "have" (source) and "want" (desired results).
I won't contribute to your post if I can't cut-and-paste your syntactically correct code into SAS.
novinosrin
Tourmaline | Level 20

very wise and thoughtful words. Hmm i didn't know many sas-l wise men are active here too. I do have a question on multiple  &&& ampersands indirect referencing which I don't wanna ask here deviating from the topic but If i'm allowed to plug you gentlemen on the question, I would do so in another separate thread. 

Quentin
Super User
I'd welcome a &&& question in a new thread, @novinosrin. While sometimes I've been frustrated by the balkanization caused by having so many different SAS comminuties online, it's fun to see who pops up where (e.g. saw you pop up on linked in the other day, celebrating hashman's 'new' base sas certification : )
BASUG is hosting free webinars Next up: Mike Raithel presenting on validating data files on Wednesday July 17. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
RW9
Diamond | Level 26 RW9
Diamond | Level 26

Too true, or even put data in datasets and merge/join/select in - and thus have the full storage of a dataset, and the full actual programming language to manipulate it.  Been saying these things for ages, but its a losing fight, even SAS themselves push this type of macro list/messy macro code out as standard on all new platforms, and set bad coding practices as default (options vartype=any for instance).  If anything its getting worse.

Kurt_Bremser
Super User

@RW9 wrote:

Too true, or even put data in datasets and merge/join/select in - and thus have the full storage of a dataset, and the full actual programming language to manipulate it.  Been saying these things for ages, but its a losing fight, even SAS themselves push this type of macro list/messy macro code out as standard on all new platforms, and set bad coding practices as default (options vartype=any for instance).  If anything its getting worse.


Yep.

<sarcasm>"So now we got us this nice atom bomb, so let's drop it!"</sarcasm>

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
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
  • 11 replies
  • 8981 views
  • 10 likes
  • 7 in conversation