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.

SAS Innovate 2025: Call for Content

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!

Submit your idea!

Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 1 reply
  • 1405 views
  • 2 likes
  • 2 in conversation