Hello
I would like to obtain &vars2, &vars3 and &vars4 automatically from &vars1
%let vars1 = Id Germ Gender PostCode DateOfDiagnosis DateOfBirth;
%let vars2 = 'Id','Germ','Gender','PostCode','DateOfDiagnosis','DateOfBirth';
%let vars3 = '_Id','_Germ','_Gender','_PostCode','_DateOfDiagnosis','_DateOfBirth';
%let vars4 = Id=_Id Germ=_Germ Gender=_Gender PostCode=_PostCode DateOfDiagnosis=_DateOfDiagnosis DateOfBirth=_DateOfBirth;
I'm able to obtain _Id_Germ_Gender_PostCode_DateOfDiagnosis_DateOfBirth_
with this :
%put %sysfunc(cat(_,%sysfunc(tranwrd(&vars1,%str( ),%str(_))),_));
So I think this should be working for &vars2 but it is not :
%put %sysfunc(cat(%str('),%sysfunc(tranwrd(&vars1,%str( ),%str(','))),%str(')));
Does anyone knows how to handle special characters like ' and , ?
Thanks
Using macro language and tranwrd is going to be too fiddley. Using this technique will allow you much more flexibility.
data test;
stop;
length Id $8 Germ $3 Gender $1 PostCode $6 DateOfDiagnosis DateOfBirth 8;
format date: date9.;
call missing(of _all_);
run;
%let vars1 = ID G: post: date:;
proc transpose data=test(obs=0) out=vars;
var &vars1;
run;
proc sql noprint;
select _name_,
quote(strip(_name_)),
quote(cats('_',_name_)),
catx('=_',_name_,_name_)
into :vars1 separated by ' ',
:vars2 separated by ',',
:vars3 separated by ',',
:vars4 separated by ' '
from vars;
quit;
run;
%put NOTE: VARS1=%superQ(vars1);
%put NOTE: VARS2=%superQ(vars2);
%put NOTE: VARS3=%superQ(vars3);
%put NOTE: VARS4=%superQ(vars4);
Using macro language and tranwrd is going to be too fiddley. Using this technique will allow you much more flexibility.
data test;
stop;
length Id $8 Germ $3 Gender $1 PostCode $6 DateOfDiagnosis DateOfBirth 8;
format date: date9.;
call missing(of _all_);
run;
%let vars1 = ID G: post: date:;
proc transpose data=test(obs=0) out=vars;
var &vars1;
run;
proc sql noprint;
select _name_,
quote(strip(_name_)),
quote(cats('_',_name_)),
catx('=_',_name_,_name_)
into :vars1 separated by ' ',
:vars2 separated by ',',
:vars3 separated by ',',
:vars4 separated by ' '
from vars;
quit;
run;
%put NOTE: VARS1=%superQ(vars1);
%put NOTE: VARS2=%superQ(vars2);
%put NOTE: VARS3=%superQ(vars3);
%put NOTE: VARS4=%superQ(vars4);
Thanks very much !
I simplified it a bit to meet my needs :
%let vars1 = Id Germ Gender PostCode DateOfDiagnosis DateOfBirth;
data test;
stop;
length &vars1 $3;
run;
proc transpose data=test(obs=0) out=vars;
var _all_;
run;
proc sql noprint;
select
quote(strip(_name_)),
quote(cats('_',_name_)),
catx('=_',_name_,_name_)
into
:vars2 separated by ',',
:vars3 separated by ',',
:vars4 separated by ' '
from vars;
quit;
run;
%_eg_conditional_dropds(test, vars);
%put &vars1;
%put &vars2;
%put &vars3;
%put &vars4;
%let vars1 = Id Germ Gender PostCode DateOfDiagnosis DateOfBirth;
data test;
stop;
length &vars1 $3;
run;
This is the part that I assumed you already have "a SAS data set".
there seem to be bugs to be ironed out in handling macro quoted arguments in the functions called through %sysfunc(). there seem to be ways to around them, though. here is one. admittedly, var4 is stretching macro a bit. 🙂
%*-- note: macro args whose name starts with an underscore character are for calling-by-name --*;
%*-- returns 1 if &&&_arg is blank, 0 otherwise --*;
%macro isBlank(_arg);
%sysevalf(%superq(&_arg) = ,boolean)
%mend isBlank;
%*-- returns &&&_str single or double quoted or as-is. macro quoted --*;
%macro qquote(_str, quote=s);
%local str sq;
%let str = %superq(&_str);
%let quote = %upcase("e);
%if %isBlank(quote) %then %do;
%*;&str
%end; %else %if "e = S %then %do;
%let sq = %str(%');
%*;&sq.%qsysfunc(transtrn(&str,&sq,&sq.&sq))&sq
%end; %else %do;
%*;%qsysfunc(quote(&str))
%end;
%mend qquote;
%*-- returns &str prefixed --*;
%macro prefix(str, prefix=);
%*;%unquote(&prefix)&str
%mend prefix;
%*-- main. returns prefixed, delimited, and quoted list --*;
%macro qcsv(_list, indlm=%str( ), dlm=%str(, ), quote=s, prefix=);
%local word i;
%let i = 1;
%let word = %qscan(%superq(&_list), &i, &indlm);
%do %while (not %isBlank(word));
%let word = %prefix(&word, prefix=&prefix);
%*;%qquote(word, quote="e)
%let i = %eval(&i + 1);
%let word = %qscan(%superq(&_list), &i, &indlm);
%if not %isBlank(word) %then %*;&dlm.;
%end;
%mend;
%*-- usage example --*;
%let vars1 = Id Germ Gender PostCode;
%put var2=%qcsv(vars1);
%put var3=%qcsv(vars1, prefix=_);
%put var4=%qcsv(vars1, quote=, prefix=%nrstr(&str=_));
%*-- on log
var2='Id', 'Germ', 'Gender', 'PostCode'
var3='_Id', '_Germ', '_Gender', '_PostCode'
var4=Id=_Id, Germ=_Germ, Gender=_Gender, PostCode=_PostCode
--*;
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.