01-15-2017 02:07 AM - edited 01-15-2017 02:38 AM
Hi SAS Folks,
I am tring to run array inside do loop to check into look back period, however to simplify writing multiple if conditions i was thinking of writing a macro to put some statements dynamically.
Here is my data looks like ( this is 2 years data factorized into 8 quarters):
infile cards truncover missover;
input trt_dur_qtr1 : $10.
trt_dur_qtr2 : $10.
trt_dur_qtr3 : $10.
trt_dur_qtr4 : $10.
trt_dur_qtr5 : $10.
trt_dur_qtr6 : $10.
trt_dur_qtr7 : $10.
trt_dur_qtr8 : $10.
- x a - - x - x+a
x+a x+a a x - x+a x x
x x - x x+a x - x
- x+a - - x a x+a a
So, what i exactly wants to do is : I want to look back into 1 quarter back for each one i,e. if my current quarter is 3( qtr3) i want my array to look back into 1st and 2nd array elements. likewise if i am in 8 th quarter array will compare (n-1) i,e into 7th..6th..upto 1st quarter. Howerver for 2 nd quarter it will compare 1st quarter only.
Here is my try:
I want to run part of macro (%do loop) when my datastep do loop is greater than eq to 3 ( from line number 47-53) . but i am not sure how to use data step do loop incremented variable for running macro do loop. Is there any way around to use data step (i) variable and store into macro for current iteration?
this code is able to put conditions dynamically but not as desired ( e.g for 3rd quarter i only need 2 conditions each for 2 look back quarter periods to be written by macro and likewise for 8th quarter , last 7 quarters)
I am attaching doc having groups i want to create depending upon look back period ( only for yellow highlighted rows i,.e for new and restart group).Also i have attached my try code for your reference. my problem lies in line number 47 to 53.
01-15-2017 06:09 AM - edited 01-15-2017 06:13 AM
but i am not sure how to use data step do loop incremented variable for running macro do loop
Macros are kind of "automatic typewriters" creating Base SAS code for you. Only when the macro processor is done, the SAS processor starts doing its job. For this reason you can't do what you're asking for (wrong timing).
It's most of the time better to not start writing macro code straight away, but to first start with pure Base SAS code and only once you've got something working, you "macrotize" the code to make it more dynamic. This way you can develop your macro step by step and test each step as you go which makes debugging and "getting it right" much much easier.
I don't fully understand what you're trying to do (especially how you decide with which array element to start to look back two) but:
In case I've got it right that you basically then look at the values of array elements -1 and -2 and based on the combination of the values then populate a new variable, you could also go for an approach where you simply concatenate the values of the two variables, implement a custom format for all the value combinations and then simply apply this format to the concatenated string.
01-15-2017 03:48 PM - edited 01-15-2017 03:53 PM
I would like to clarify few points of your post:
1) Why all TRT_DUR_QTRn are defined as $10. wheile max length is 3 characters ('x+a') ?
2) I can understand two objects comapre.
Your post: "if my current quarter is 3( qtr3) i want my array to look back into 1st and 2nd array elements." etc.
What do you ean by look back into 1st and 2nd elements ? what do yo you want to do do with them ?
3) line 55 contains "else if &tpoint._range[i-1] ='No Drug' " - where did 'No Drug' come from ?
4) As your input contains only 4 distinct values, i.e. '-' , 'a', 'x' , 'x+a' there are (4X4) 16 combinations of previous-current value
gathered into 7 group codes according to your macro:
proc format lib=work; value group 1 = '1.New' /* ?x */ 2 = '2.Win' /* ax */ 3 = '3.Extension' /* ax+a */ 4 = '4.Discontinue' /* x- */ 5 = '5.Lose' /* x+aa */ 6 = '6.Repeat' /* xx xx+a x+ax x+ax+a */ 7 = '7.Not Defined' /* -- -a a- aa */ ; run;
5) finally you can simplify your code (just drop extra variables) without using macro code:
%let qtr_hbound=8; proc format lib=work; value group 1 = '1.New' /* ?x */ 2 = '2.Win' /* ax */ 3 = '3.Extension' /* ax+a */ 4 = '4.Discontinue' /* x- */ 5 = '5.Lose' /* x+aa */ 6 = '6.Repeat' /* xx xx+a x+ax x+ax+a */ 7 = '7.Not Defined' /* -- -a a- aa */ ; run; data test1; infile cards truncover /*missover*/; input a_line $60.; length trt_dur_qtr1-trt_dur_qtr&qtr_hbound $3 groupx $6; array trtx (&qtr_hbound) $ trt_dur_qtr1-trt_dur_qtr&qtr_hbound; array grpn group1-group&qtr_hbound; format group1-group&qtr_hbound group15.; do i=1 to &qtr_hbound; trtx(i) = scan(a_line,i,' '); if i>1 then do; groupx = cats(trtx(i-1),trtx(i)); /* put groupx=; */ select (groupx); when('ax') grpn(i)=2; when ('ax+a') grpn(i)=3; when ('x-') grpn(i)=4; when ('x+aa') grpn(i)=5; when ('xx','xx+a','x+ax','x+ax+a') grpn(i)=6; otherwise grpn(i)=7; end; end; else if trtx(i) = 'x' then group1=1; else group1=7; /* else ? */ end; cards; - x a - - x - x+a x+a x+a a x - x+a x x x x - x x+a x - x - x+a - - x a x+a a ; run;