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!
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;
Limit your scenario to minimum together with the MLOGIC SYMBOLGEN MPRINT options.
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?
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.
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)
OBS | Event_1_type | Event_1_drug | Event_2_type | Event_2_drug | Event_3_type | Event_3_drug |
1 | 2 | . | . | . | . | . |
2 | 2 | 0 | 1 | 1 | 1 | 0 |
3 | 3 | 0 | 2 | 0 | 3 | 0 |
4 | 4 | 0 | . | . | . | . |
5 | 1 | 0 | . | . | . | . |
What I want is:
OBS | Event_1_type | Event_1_drug | Event_2_type | Event_2_drug | Event_3_type | Event_3_drug | EP_A | EP_A_ondrug | EP_A_offdrug | EP_B | EP_B_ondrug | EP_B_offdrug |
1 | 2 | 0 | . | . | . | . | 0 | 0 | 0 | 1 | 0 | 1 |
2 | 1 | 0 | 1 | 1 | 1 | 0 | 3 | 1 | 2 | 0 | 0 | 0 |
3 | 3 | 0 | 2 | 0 | 3 | 0 | 0 | 0 | 0 | 3 | 0 | 0 |
4 | 4 | 0 | . | . | . | . | 0 | 0 | 0 | 0 | 0 | 0 |
5 | 1 | 0 | 3 | 0 | . | . | 1 | 0 | 1 | 1 | 0 | 0 |
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 |
---|---|---|
A | 1 | ... If Event_&i._type IN(1) then .... |
B | 2,3 | ... If Event_&i._type IN(2,3) then ... |
C | 1,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.
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;
Don't miss out on SAS Innovate - Register now for the FREE Livestream!
Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.
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.