DATA Step, Macro, Functions and more

Using the let statement to call later in a macro

Reply
Contributor
Posts: 57

Using the let statement to call later in a macro

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.

Frequent Contributor
Posts: 78

Re: Using the let statement to call later in a macro

Posted in reply to lisahoward

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

data x;

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

run;

Contributor
Posts: 57

Re: Using the let statement to call later in a macro

Posted in reply to TarunKumar

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.

Super User
Super User
Posts: 7,997

Re: Using the let statement to call later in a macro

Posted in reply to lisahoward

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.

Contributor
Posts: 57

Re: Using the let statement to call later in a macro

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.

Super User
Super User
Posts: 7,997

Re: Using the let statement to call later in a macro

Posted in reply to lisahoward

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;

Super User
Posts: 5,518

Re: Using the let statement to call later in a macro

Posted in reply to lisahoward

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.

Ask a Question
Discussion stats
  • 6 replies
  • 377 views
  • 0 likes
  • 4 in conversation