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

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

1 ACCEPTED SOLUTION

Accepted Solutions
data_null__
Jade | Level 19

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);

View solution in original post

4 REPLIES 4
data_null__
Jade | Level 19

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);

mathias
Quartz | Level 8

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;

data_null__
Jade | Level 19

%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".

chang_y_chung_hotmail_com
Obsidian | Level 7

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(&quote);
 
    %if %isBlank(quote) %then %do;
      %*;&str
    %end; %else %if &quote = 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=&quote)
      %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
  --*;

SAS Innovate 2025: Register Now

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!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 4 replies
  • 2991 views
  • 1 like
  • 3 in conversation