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

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!

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
  • 1900 views
  • 6 likes
  • 7 in conversation