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

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.

1 ACCEPTED SOLUTION

Accepted Solutions
s_lassen
Meteorite | Level 14

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

4 REPLIES 4
art297
Opal | Level 21

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

 

Kurt_Bremser
Super User

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.

Tom
Super User Tom
Super User

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

 

s_lassen
Meteorite | Level 14

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?

 

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

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