BookmarkSubscribeRSS Feed
lisahoward
Calcite | Level 5

I have the following let statement as I want to create a macro data step rather than having to individually call out each drug name  in a separate line of code:

%let drug = ( 'CARBOPLATIN'  'ABARELIX ABS'  'ABIRATERONE'  'AFINTONIB' 'ALDESLEUKIN' )  ***and about 100 more drugs which i haven't listed)

data x;

  set y;

if index(upcase(GENERIC),&drug) >0 ;

run;

  However I keep getting the following error message.  I can't figure out where I am going wrong.  Any suggestions would be great .   Just to note i tried indexW and got the same error. thanks.

NOTE: Line generated by the macro variable "drug".

640  ( 'CARBOPLATIN'  'ABARELIX ABS'  'ABIRATERONE'  'AFINTONIB'  'ALDESLEUKIN')

                     ----------

                     388

                    

ERROR 388-185: Expecting an arithmetic operator.

ERROR 76-322: Syntax error, statement will be ignored.

6 REPLIES 6
TarunKumar
Pyrite | Level 9

%let drug =  'CARBOPLATIN ABARELIX ABS ABIRATERONE  AFINTONIB ALDESLEUKIN';

data x;

y=  indexw(&drug,"ABARELIX")  ;

run;

lisahoward
Calcite | Level 5

Hi I am not sure the above would work as they are all different drugs in the % let statement. and in the datastep you are still calling out each drug e..g. ABARELIX.  What i am ultimately trying to do is not repeat the same datastep for every single drug type as there are over 100 so for example how can i  get the following three steps in to one step that calls the drug name as a macro variable.

I am trying to make a macro out of the following statement.  Here we just have two drugs so don't need a macro but in my program there are over a 100 drugs.  I want to put the drugs in a let statement to call throughout my program.

Currently

data x ;

  set y;

  if  index(upcase(GENERIC_NAME),'drug_a')>0 or

                                         index(upcase(GENERIC_NAME),'drug_b')>0) ;

run;

Trying to change it to:

%let drug=('drug_a' 'drug_b');

data x;

  set y;

if index(upcase(GENERIC),&drug) >0 ;

run;

but i get the error:

                   

ERROR 388-185: Expecting an arithmetic operator.

ERROR 76-322: Syntax error, statement will be ignored.

RW9
Diamond | Level 26 RW9
Diamond | Level 26

Hi,

You are getting the error because of this (this is what the compiler sees after macro decoded):

if index(upcase(GENERIC),('drug_a' 'drug_b')) >0 ;

As you can see from the above this is not how the index function works so you get the errors.

You could update the macro to loop over the macro using %scan to get each one out.  Its a bit of a faff though.  Might I ask what you are trying to achieve as I would assume there are better solutions than using a macro variable - for instance you are going to hit the maximum length quickly.

One suggestion is:

data drugs;

     drug="Drug A"; output;

     drug="Drug B"; output;

     drug="Drug C"; output;

run;

data _null_;

     set drugs;

     call execute('data '||strip(drug)||';

                                set have;

                                if index(upcase(GENERIC),'||strip(drug)||') >0 ;

                           run;');

run;

This will generate a datastep for each row in drugs with the condition to output if generic in have has the word from the dataset drug.

Other alternatives can be had depending on scenario.

Just to add on the above data _null_ method, the drugs dataset can be separate from the data, updated as and when, and also be any size without changing the main program.  For instance if you hardcode your drug list, then you need to update the program if any new drugs are added etc. With this you could for instance use ATC Coding datasets.

lisahoward
Calcite | Level 5

Thank you RW9. Basically I am just trying to get a dataset with all patients that have a record of the drugs specified and leave the rest of the unspecified drugs behind.

RW9
Diamond | Level 26 RW9
Diamond | Level 26

Well, I would just code that in then:

proc sql;

     create table WANT as

     select     PATIENT

     from       HAVE

     where     DRUG in ('Drug A','Drug B','Drug C');

quit;

Astounding
PROC Star

Lisa,

The real problem is that INDEX is the wrong tool for the job.  You could use your original %LET statement (which includes parentheses around the quoted names) in this fashion:

if upcase(GENERIC) in &drug;

Good luck.

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
  • 6 replies
  • 1626 views
  • 0 likes
  • 4 in conversation