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

how is it possible to get from this list:

%let types = 
	'TYPE 1'
	'TYPE 2';

to this list, programmatically:

%let new = 
	AT_TYPE_1
	AT_TYPE_2;

My unsuccessful attempt:

%let new= %sysfunc(translate(&types, '_',' '));
1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

For your specific example you could possible get away with something like this that just changes the 'TYPE ' to 'AT_TYPE_' and then removes the qutoes.

 

 

%let new=%sysfunc(compress(%sysfunc(tranwrd(&types,%str(TYPE ),AT_TYPE_)),%str(%')));

But if this is just an example of a larger problem of converting a space delimited list of quoted values into a space delimited unquoted values with any embedded spaces converted to underscores then you will need a loop.  Probably easier to do in a data step than in macro.

  

data _null_;
  length types new $32767 ;
  types = symget('types');
  do i=1 to countw(types,' ','q');
    new = catx(' ',new,translate(catx(' ','AT',dequote(scan(types,i,' ','q'))),'_',' '));
  end;
  call symputx('new',new);
  stop;
run;

 If you did need to do total in macro code then perhaps you could use a function style macro.

%macro labels_to_names(labels,prefix=);
%local i;
%do i=1 %to %sysfunc(countw(&labels,%str( ),q));
 %sysfunc(translate(&prefix %sysfunc(dequote(%scan(&labels,&i,%str( ),q))),_,%str( )))
%end;
%mend labels_to_names;

%let new=%labels_to_names(&types,prefix=AT);

View solution in original post

8 REPLIES 8
Reeza
Super User

How is the first variable determined? Is there a way to go back and fix at source?

mduarte
Quartz | Level 8

I need to use both versions...

PGStats
Opal | Level 21

Maybe you can work something out from the following snippet

 

%let types = 
	'TYPE 1'
	'TYPE 2';

data _null_;
call symputx("new",prxchange("s/'(\D+)\s+(\d+)'/AT_\1_\2/i",-1,"&types"));
run;

%put &new;
PG
Ksharp
Super User

You can achieve that via data step or macro . I suggest including them all into  a macro.

 


    
%macro change(t=);
 %let n=%sysfunc(countw(&t ,%str(%') ));
 %do i=1 %to &n ;
  %let temp=%scan(&t, &i ,%str(%'));
  %if %length(&temp) ne 0 %then %do; 
   AT_%sysfunc(translate(&temp,_,%str( )))
  %end;
 %end;
%mend;


%let types = 
	'TYPE 1'
	'TYPE 2';	
%let want=%change(t=&types)  ;

%put NOTE: &want ;
andreas_lds
Jade | Level 19

Do you have to create the let-statement or do you just need new to be set properly?

 

If you are interested in the value, try:

%let new = %sysfunc(tranwrd(%sysfunc(compress(&types, %str(%'))), %str(TYPE ), %str(AT_TYPE_)));
Tom
Super User Tom
Super User

For your specific example you could possible get away with something like this that just changes the 'TYPE ' to 'AT_TYPE_' and then removes the qutoes.

 

 

%let new=%sysfunc(compress(%sysfunc(tranwrd(&types,%str(TYPE ),AT_TYPE_)),%str(%')));

But if this is just an example of a larger problem of converting a space delimited list of quoted values into a space delimited unquoted values with any embedded spaces converted to underscores then you will need a loop.  Probably easier to do in a data step than in macro.

  

data _null_;
  length types new $32767 ;
  types = symget('types');
  do i=1 to countw(types,' ','q');
    new = catx(' ',new,translate(catx(' ','AT',dequote(scan(types,i,' ','q'))),'_',' '));
  end;
  call symputx('new',new);
  stop;
run;

 If you did need to do total in macro code then perhaps you could use a function style macro.

%macro labels_to_names(labels,prefix=);
%local i;
%do i=1 %to %sysfunc(countw(&labels,%str( ),q));
 %sysfunc(translate(&prefix %sysfunc(dequote(%scan(&labels,&i,%str( ),q))),_,%str( )))
%end;
%mend labels_to_names;

%let new=%labels_to_names(&types,prefix=AT);
mduarte
Quartz | Level 8

Thanks - I used the data step method as I found it adapted very easily to the true original list of items, which weren't actually TYPE 1, TYPE 2 etc.

RW9
Diamond | Level 26 RW9
Diamond | Level 26

The easiest way is to use Base SAS - which is designed to process and manipulate data, rather than Macro language which is designed to generate text, here are some verbose examples of generating macro variables from code, or using a dataset in programming rather than macro variables:

data myparameters;
  param="SEX"; 
  val="M"; output;
  val="F"; output;
run;

/* Create some macro variables from my parameters */
data _null_;
  set myparameters;
  by param;
  length string1-string3 $200;
  retain string1 string2 string3;
  string1=catx(" ",string1,val);
  string2=catx(",",string2,val);
  string3=cat(strip(string3),",'",strip(val),"'");
  if last.param then do;
    call symput('string1',string1);
    call symput('string2',string2);
    call symput('string3',string3);
  end;
run;
%put &string1.;
%put &string2.;
%put &string3.;

/* Or we could just use that parameter dataset in code and not need macro at all */
proc sql;
  create table WANT as
  select * from SASHELP.CLASS where SEX in (select VAL from MYPARAMETERS where PARAM="SEX");
quit;

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

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
  • 8 replies
  • 1930 views
  • 6 likes
  • 7 in conversation