DATA Step, Macro, Functions and more

not able tio understand what the code is doing

Accepted Solution Solved
Reply
Frequent Contributor
Posts: 116
Accepted Solution

not able tio understand what the code is doing

i have a below macro program and i am unable to get the required result and understand what is going on.

%macro nsd(ArmVar   = ACTARM,LstCols  = %quote(USUBJID SEX AGE RACE WEIGHTBL);

%let totval=%eval(%sysfunc(countc(&LstCols,%str( )))+1);

%let LstCols_u=%sysfunc(tranwrd(&LstCols,subjid,usubjid_use));
%let LstCols_use=%sysfunc(tranwrd(&LstCols_u.,race,race_use));

data inc;
    set adae;
length patinf $200 patlbl $500 usubjid_use $40 race_use $50;

usubjid_use=scan(usubjid,3,'-');
race_use=upcase(substr(race,1,2));

%do i=1 %to &totval;
%if %upcase(%scan(&LstCols_use,&i)) eq %upcase(&ArmVar.) %then %do;
patinf=catx("/",patinf,&armvar.);
if _n_=1 then patlbl=catx("/",patlbl,"Treatment");
%end;
%else %do;
patinf=catx("/",patinf,(%scan(&LstCols_use,&i)));
if _n_=1 then patlbl=catx("/",patlbl,vlabel(%scan(&LstCols,&i)));
%end;
%end;
if _n_=1 then do;
call symputx("patlbl",patlbl ,'L');
run;

 

 

the thing which i am not getting is for race i am scanning and need the first 2 letters of it.

 

Can anyone explain what the code is doing.


Accepted Solutions
Solution
‎05-23-2017 02:45 AM
PROC Star
Posts: 63

Re: not able tio understand what the code is doing

As shown, your code will not accomplish very much, for a couple of reasons:

  1. The macro declaration has an unmatched paranthesis (the last right paranthesis closes the %QUOTE call, not the macro header).
  2. There is no %MEND statement, and no code that calls the macro

Apart from that, I think your problem is with these statements:

%let LstCols_u=%sysfunc(tranwrd(&LstCols,subjid,usubjid_use));
%let LstCols_use=%sysfunc(tranwrd(&LstCols_u.,race,race_use));

The problem being that the parameters to the function calls are lower case, but it seems that the LstCols macro variable contains uppercase letters. So you will never get RACE translated to RACE_USE. To make it work, try

%let LstCols=%upcase(&LstCols); /* not necessary here, but just in case the parameter is lower case */
%let LstCols_u=%sysfunc(tranwrd(&LstCols,SUBJID,USUBJID_USE)); %let LstCols_use=%sysfunc(tranwrd(&LstCols_u.,RACE,RACE_USE));

What the code does otherwise? Not really sure, what is it supposed to do?

 

View solution in original post


All Replies
PROC Star
Posts: 7,364

Re: not able tio understand what the code is doing

Can't evaluate for you as the code is incomplete AND you didn't provide either an example dataset OR a call to the macro.

 

However, the first line is problematic in itself. You declare a SAS macro, but don't have a closing parenthesis. I was initially going to ask if the %quote was necessary, but didn't look any further after I noticed the missing parenthesis and the fact that the macro didn't end with a %mend; statement.

 

Art, CEO, AnalystFinder.com

 

Super User
Posts: 6,966

Re: not able tio understand what the code is doing

[ Edited ]

The first thing I see is that the macro definition is missing a closing parenthesis. Let yourself be helped by the Enhanced Editor, it shows you the  matching bracket when you position the cursor on one.

 

Next, there's part of the macro missing, as there is no %mend statement, and you don't show us how you call the macro.

 

Next, I can see no example data in your post against which we could test the code.

 

Please rectify all points mentioned above.

 

And please use the "little running man" icon to post code, so it does not appear in this spaghetti fashion.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Super User
Super User
Posts: 6,502

Re: not able tio understand what the code is doing

[ Edited ]

It is much easier if you pull the name from the list into a local macro variable.

You can also force the input values to uppercase to make the code later easier.  Perhaps refactoring the code a little will make it easier to see what it is doing.  I removed the extra RACE_USE and USUBJID_USE variables since they didn't seem necessary.

 

%macro nsd
(ArmVar= ACTARM
,LstCols= USUBJID SEX AGE RACE WEIGHTBL
);
%local totval var;
%* Count number of variables ;
%let totval=%sysfunc(countw(&lstcols,%str( ));
%* Force parameters to uppercase ;
%let armvar=%upcase(&armvar);
%let lstcols=%upcase(&lstcols);

data inc;
  set adae;
  length patinf $200 patlbl $500 ;
%do i=1 %to &totval;
%* Get variable name and adjust RACE and USUBJID ;
  %let var=%scan(&lstcols,&i,%str( ));
  %if &var=RACE %then %let var=upcase(substr(race,1,2)) ;
  %if &var=USUBJID %then %let var=scan(usubjid,3,'-');

* Aggregate column values ;
  patinf=catx("/",patinf,&var);

* Aggregate column labels - replace treatment arm with Treatement ;
  %if &var = &armvar %then %do;
  if _n_=1 then patlbl=catx("/",patlbl,"Treatment");
  %end;
  %else %do;
  if _n_=1 then patlbl=catx("/",patlbl,&var);
  %end;
%end;
* Generate macro variable ;
  if _n_=1 then call symputx("patlbl",patlbl ,'L');
run;
* ... ;
%mend;

%nsd
(ArmVar= ACTARM
,LstCols= USUBJID SEX AGE RACE WEIGHTBL
);

 

Solution
‎05-23-2017 02:45 AM
PROC Star
Posts: 63

Re: not able tio understand what the code is doing

As shown, your code will not accomplish very much, for a couple of reasons:

  1. The macro declaration has an unmatched paranthesis (the last right paranthesis closes the %QUOTE call, not the macro header).
  2. There is no %MEND statement, and no code that calls the macro

Apart from that, I think your problem is with these statements:

%let LstCols_u=%sysfunc(tranwrd(&LstCols,subjid,usubjid_use));
%let LstCols_use=%sysfunc(tranwrd(&LstCols_u.,race,race_use));

The problem being that the parameters to the function calls are lower case, but it seems that the LstCols macro variable contains uppercase letters. So you will never get RACE translated to RACE_USE. To make it work, try

%let LstCols=%upcase(&LstCols); /* not necessary here, but just in case the parameter is lower case */
%let LstCols_u=%sysfunc(tranwrd(&LstCols,SUBJID,USUBJID_USE)); %let LstCols_use=%sysfunc(tranwrd(&LstCols_u.,RACE,RACE_USE));

What the code does otherwise? Not really sure, what is it supposed to do?

 

☑ This topic is solved.

Need further help from the community? Please ask a new question.

Discussion stats
  • 4 replies
  • 158 views
  • 2 likes
  • 5 in conversation