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
--*;
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
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.
Ready to level-up your skills? Choose your own adventure.