DATA Step, Macro, Functions and more

Change the arguments for IN based on the current value within macro

Accepted Solution Solved
Reply
Occasional Contributor
Posts: 11
Accepted Solution

Change the arguments for IN based on the current value within macro

I use the following macro to count certain events within observations. The data structure is:

ID

Index_date

Event_1_type

Event_1_date

Event_1_drug

--

Event_4_type

Event_4_date

Event_4_drug

ep denotes certain (combined) endpoints: A, B and C.

End point A corresponds to event type 1

End point B corresondes to event type 2 and 3

End point C corresponds to event type 1,2, 3 and 4.

%macro count1(all_eps);

  %let k=1;

  %let ep = %scan(&all_eps, &k);

  %do %while("&ep" NE "");

*/ I assume I have to put some code here to get it working */

  EP_&ep._nr = 0;

  EP_&ep._ondrug =0;

  EP_&ep._offdrug = 0;

  %do i=4 %to 1 %by -1;

  If Event_&i._type IN(&eventtype.) then

  do;

  EP_&ep._nr = EP_&ep._nr+1;

  if Event_&i._drug = 1 then

  do;

  EP_&ep._ondrug = EP_&ep._ondrug +1;

  end;

  Else

  do;

  EP_&ep._offdrug = EP_&ep._offdrug +1;

  end;

  end;

  If (EP_&ep._ondrug+EP_&ep._offdrug) ne EP_&ep._nr then

  do;

  Put 'WARNING: missing drug use information'/ ID=//;

  end;

  %let k = %eval(&k + 1);

  %let ep = %scan(&all_eps, &k);

  %end;

%mend count1;

%count1(A B C);

run;

What I can't seem to get working is to let '&eventtype.' that is used as the arguments for the IN expression be either '1', '2,3' or ; '1,2,3,4; ; pending on the current value of ep. It has to be something like, but I can't get in working within the macro;

If ep = A then do;

eventtype = 1

end;

else if ep = B then do;

eventtype = %str(2,3);

end;

else if ep = C then do;

eventtype = %str(1,2,3,4);

end;

Thank you for your help!


Accepted Solutions
Solution
‎01-30-2015 03:17 PM
Occasional Contributor
Posts: 11

Re: Change the arguments for IN based on the current value within macro

I've found it myself. I've added the code

%if %sysevalf(&ep = A) %then

  %do;

  %let eventtype = 1;

  %end;

  %ELSE %if %sysevalf(&ep = B) %then

  %do;

  %let eventtype = %str(2,3);

  %end;

  %ELSE %if %sysevalf(&ep = C) %then

  %do;

  %let eventtype = %str(1,2,3,4);

  %end;

View solution in original post


All Replies
Super User
Posts: 5,427

Re: Change the arguments for IN based on the current value within macro

Limit your scenario to minimum together with the MLOGIC SYMBOLGEN MPRINT  options.

Data never sleeps
Occasional Contributor
Posts: 11

Re: Change the arguments for IN based on the current value within macro

I'm sorry, I don't quite understand. Why do you want me to run with these options? Do you mean as a debug technique? Or do you want to see the logs with these options?

Super User
Posts: 11,343

Re: Change the arguments for IN based on the current value within macro

If this is used as part of a datastep I'd look  very closely if I need some of this macro coding.

The loop with seems to be very tied to some fixed variables Event_1_type,Event_2_type,Event_3_type and Event_4_type which makes me think that loop is a likely candidate for an array process.

Is your data structure actually a single column (variable) with those types of values or are those just the variable names?

Can you provide a few rows of data, a description of what your are attempting and an example of what the output for those rows of data would look like.

It is very hard to make much suggestion regarding &eventtype as you don't show where it is assigned or created.

Occasional Contributor
Posts: 11

Re: Change the arguments for IN based on the current value within macro

Thanks.

What actually happens in each of the 4 do loops is a bit more elaborate than the sample I provided (but that works). Below a few rows of data (limited to Event_3 and Endpoint B, for brevity)

OBSEvent_1_typeEvent_1_drugEvent_2_typeEvent_2_drugEvent_3_typeEvent_3_drug
12.....
2201110
3302030
440....
510....

What I want is:

OBSEvent_1_typeEvent_1_drugEvent_2_typeEvent_2_drugEvent_3_typeEvent_3_drugEP_AEP_A_ondrugEP_A_offdrugEP_BEP_B_ondrugEP_B_offdrug
120....000101
2101110312000
3302030000300
440....000000
51030..101100

The first event for case 1 was 'type 2', which is part of endpoint B. It was not while using the drug; so EP_B_offdrug = 1 and EP_B_ondrug = 0.

Case 2 had 3 events, all from 'type 1'. Type 1 is part of endpoint A. The second one was while using the drug, the other two not, hence EP_A_ondrug = 1 and EP_A_offdrug = 2

Case 4 had a type 4 event, which is not part of endpoint A or B, hence the zero's.

It is very hard to make much suggestion regarding &eventtype as you don't show where it is assigned or created.

Sorry about that. I've removed the syntax in which I tried to assign it, since it didn't work. You can see my comment on where it was. I want to link a certain endpoint with a string(?) of numbers to be put in as arguments for the IN in line   If Event_&i._type IN(&eventtype.) then.


To put it differently, I want this (very much shortened, there are more endpoints and more eventtypes) to happen:

while ep =eventtype = submitted code
A1... If Event_&i._type IN(1) then ....
B2,3... If Event_&i._type IN(2,3) then ...
C1,2,3,4... If Event_&i._type IN(1,2,3,4) then ...

Where the value of the eventtype macro variable are used to see if Event_&i._type corresponds to the event types I'm looking for.

Solution
‎01-30-2015 03:17 PM
Occasional Contributor
Posts: 11

Re: Change the arguments for IN based on the current value within macro

I've found it myself. I've added the code

%if %sysevalf(&ep = A) %then

  %do;

  %let eventtype = 1;

  %end;

  %ELSE %if %sysevalf(&ep = B) %then

  %do;

  %let eventtype = %str(2,3);

  %end;

  %ELSE %if %sysevalf(&ep = C) %then

  %do;

  %let eventtype = %str(1,2,3,4);

  %end;

🔒 This topic is solved and locked.

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

Discussion stats
  • 5 replies
  • 255 views
  • 0 likes
  • 3 in conversation