BookmarkSubscribeRSS Feed
chrissowden
Obsidian | Level 7

I have writing a transpose macro and I am trying to get the macro variable by statement if there is no by variables then run a transpose without the by. if there is a by statement then run the transpose with the by statement. In the code below I have it with a by statement and it works. But if the data doesn't need a by statement then it will produce errors.

 

 

%MACRO transpose (DATAIN=,DATAOUT=,BY=,ID=,IDLABEL=,
VAR= ,Prefix=);

%global dset nvars nobs;
%let dset=&datain;
%let dsid = %sysfunc(open(&dset));
%if &dsid %then %do;

%let nobs =%sysfunc(attrn(&dsid,NOBS)); /* counts number of obs */
%let nvars=%sysfunc(attrn(&dsid,NVARS));/* counts number of variables in dataset */
%let rc = %sysfunc(close(&dsid));/* close the dataset */
%put &dset has &nvars variable(s) and &nobs observation(s).;/*prints out the values of &dset and &nvars to log */
%end;
%else
%put Open for data set &dset failed - %sysfunc(sysmsg());/*if the data set in the datain is not a dataset in work lib then it will print error message to log*/

proc sort data=&datain noduprecs dupout=duplicates;by &by;run;/*checks the &datain for duplicate records*/

proc sql; select count(*) into: ia from duplicates; quit;/*store counts into ia*/

/* if the datain has ID values the occur twice in the by group statement then it will create a data set using &dataout with error message */
%if &ia ^= 0 %then %do;

data &dataout;

col="The ID value xxxxxxxx occurs twice in the same BY group";
run;

%end;

/* if no repeat values then run the rest of the macro code*/
%if &ia = 0 %then %do;


/* sort macro*/
%let sortstr=&by;
%macro issorted(dsname);
%let dsid=%sysfunc(open(&dsname));
%if (&dsid=0) %then
%put MSG=%sysfunc(sysmsg());
%else %do;
%let seq=%sysfunc(attrc(&dsid,sortedby));/*sortedby indicates how the dataset is sorted but does not sort the data*/

%let rc=%sysfunc(close(&dsid));
%if %sysfunc(strip(&sortstr)) ne %sysfunc(strip(&seq)) %then %do;
proc sort data=&dsname;
by &sortstr;
run;

%end;
%else %put A sort was not required;
%end;
%mend;
%issorted(&datain);

 

%if %sysfunc(exist(&datain)) %then %do;

PROC TRANSPOSE DATA = &datain
OUT = &dataout(DROP = _name_)
PREFIX = &prefix;

BY &by ;
VAR &var;
ID &id;
RUN;
%end;
%else %if %sysfunc(exist(&datain))= 0 %then %do ;
%put the data set &datain does not exist.;
%end;

options mprint mlogic;
%end;
%MEND;

1 REPLY 1
andreas_lds
Jade | Level 19

You need something like

%if %length(&By.) %then %do;
  by &By,;
%end;

in your proc transpose.