DATA Step, Macro, Functions and more

Nested do loop tertiles

Accepted Solution Solved
Reply
Contributor
Posts: 25
Accepted Solution

Nested do loop tertiles

Hi,

 

I am trying to create 10 tertile variables (TERT1-TERT10), which based on a variable titled PA_AVG on a five point scale, increase by 0.1, and have lower bound second tertile cut offs starting at 2.5, and ending at 3.4. The second tertile upper bound cutoffs start at 3.5 and end at 4.4, increasing by .10.

 

So, category one in TERT1 would be 0 to 2.4, category two 2.5 to 3.5, and category three, 3.6 to five. Category one in TERT2 would be 0<CAT_ONE<2.6, category two, 2.6<=CAT_TWO<=3.6, and category three, 3.6<CAT_THREE<=5, and so on until TERT10 with a second tertile cut off of 3.4 and 4.4 has been completed.

 

I am using a nested do loop, but the code isn’t executing (it just keeps running):

 

data temp;

set rank_tert;

 

do I=2.5 to 3.4 by 0.1;

do J=3.5 to 4.4 by 0.1;

do TERT=1 to 10 by 1;

 

if 0<PA_AVG<(I) then TERT=1;

else if (I)<=PA_AVG<=(J) then TERT=2;

else TERT=3;

 

end;

end;

end;

 

keep PID_PDE TERT1-TERT10;

 

run;

 

Not sure what I am doing wrong, but it may have something to do with how I am creating the 'TERT' variable? Thanks in advance for any help!

 

Emily

 


Accepted Solutions
Solution
‎11-20-2017 02:45 PM
Super User
Super User
Posts: 8,267

Re: Nested do loop tertiles

[ Edited ]
Posted in reply to epstewart1110

Assuming you want to slide your window to the right by one tenth so that you get ten windows you could do something like this.

This will create temporary arrays to store the bounds. It stores the bounds as integers to take advantage of the integer range specifications to make it easier to specify the bounds as initial vlaues for the array. Just remember to divide by ten when comparing the actual values.

To set TERT values to 0,1,2 you can take advantage of SAS evaluating boolean expressions to 0/1.  So if it is in the middle group it is greater than lower bound but not greater than upper bound only one of the two expressions is true and the result is 1. But if it falls in the higher group then both are true so the result is 2.

data temp;
  set rank_tert;
  array tert (10) ;
  array lower (10) _temporary_ (25:34);
  array upper (10) _temporary_ (35:44);
  do i=1 to dim(tert);
    tert(i)= (pa_avg >= lower(i)/10) + (pa_avg > upper(i)/10);
  end;
  drop i;
run;

 

View solution in original post


All Replies
Trusted Advisor
Posts: 1,389

Re: Nested do loop tertiles

Posted in reply to epstewart1110

You are assigning TERT a value of 1,2, or 3 inside a loop that is defined as "DO TERT=1 to 10".   As a result the terminating condition of the loop (TERT>10) is never attained.

Contributor
Posts: 25

Re: Nested do loop tertiles

[ Edited ]

Ok, thanks that makes sense.

 

So, is this correct?

 

 

data temp;

set rank_tert;

 

array tert(i) TERT1-TERT10;

 

do I=2.5 to 3.4 by 0.1;

do J=3.5 to 4.4 by 0.1;

do i=1 to 10;

 

if 0<PA_AVG<(I) then tert(i)=1;

else if (I)<=PA_AVG<=(J) then tert(i)=2;

else tert(i)=3;

 

end;

end;

end;

 

keep PID_PDE TERT1-TERT10;

 

run;

 

 

Thanks

Trusted Advisor
Posts: 1,389

Re: Nested do loop tertiles

Posted in reply to epstewart1110

Test it and see.

Super User
Posts: 13,913

Re: Nested do loop tertiles

Posted in reply to epstewart1110

epstewart1110 wrote:

Ok, thanks that makes sense.

 

So, is this correct?

 

 

data temp;

set rank_tert;

 

array tert(i) TERT1-TERT10;

 

do I=2.5 to 3.4 by 0.1;   <= If this is an upper case i

do J=3.5 to 4.4 by 0.1;

do i=1 to 10;                  <= you'll have issues because of this i , k would be more traditional

 

if 0<PA_AVG<(I) then tert(i)=1;

else if (I)<=PA_AVG<=(J) then tert(i)=2;

else tert(i)=3;

 

end;

end;

end;

 

keep PID_PDE TERT1-TERT10;

 

run;

 

 

Thanks


 

Contributor
Posts: 25

Re: Nested do loop tertiles

Thank you for your reply, ballardw.

 

I did change the initial from i to K, however, I received an error saying "Mixing of implicit and explicit array subscripting is not allowed."

 

I think it's because I included the array reference for only one variable, then tried to incorporate two stand-alone do statements. Ideally, I would like to create the tert variables without an array reference. Not sure if that's possible...

 

Thanks

 

Emily

Super User
Super User
Posts: 8,267

Re: Nested do loop tertiles

[ Edited ]
Posted in reply to epstewart1110

This statement is not clear and the code you attempted is even more confusing.

I am trying to create 10 tertile variables (TERT1-TERT10), which based on a variable titled PA_AVG on a five point scale, increase by 0.1, and have lower bound second tertile cut offs starting at 2.5, and ending at 3.4. The second tertile upper bound cutoffs start at 3.5 and end at 4.4, increasing by .10.

 

Please post input and output data. 

It does not look you have much data, but if you do limit it to just enough values/variables to demonstrate the problem you are having.

 

What I got from your question is that you want to create 10 variables from one.  Not sure how the ten variables relate to the concept of TERTILEs which would imply transforming a continuous variable into three categories.  How to you get to 10 from 3?

 

The second sentence makes it seem like you want to define multiple different pairs of cutoff values. Sounds like want the lower bound to range from 2.5 to 3.4 by 0.1 and the upper bound to range from 3.5 to 4.4 by 0.1.  Do they move together so that you generate 10 pairs?

lower_start=2.5;
upper_start=3.5;
do diff=0.0 to 0.9 by 0.1 ;
  lower=lower_start+diff;
  upper=upper_start+diff;
  output;
end;

or independently so that you generate 10*10=100 pairs?

do lower=2.5 to 3.4 by 0.1 ;
  do upper=3.5 to 4.4 by 0.1 ;
     output;
  end;
end;

Once you have these 10 or 100 sets of cut-off pairs how are you then going to apply them to your measured variable?

 

Solution
‎11-20-2017 02:45 PM
Super User
Super User
Posts: 8,267

Re: Nested do loop tertiles

[ Edited ]
Posted in reply to epstewart1110

Assuming you want to slide your window to the right by one tenth so that you get ten windows you could do something like this.

This will create temporary arrays to store the bounds. It stores the bounds as integers to take advantage of the integer range specifications to make it easier to specify the bounds as initial vlaues for the array. Just remember to divide by ten when comparing the actual values.

To set TERT values to 0,1,2 you can take advantage of SAS evaluating boolean expressions to 0/1.  So if it is in the middle group it is greater than lower bound but not greater than upper bound only one of the two expressions is true and the result is 1. But if it falls in the higher group then both are true so the result is 2.

data temp;
  set rank_tert;
  array tert (10) ;
  array lower (10) _temporary_ (25:34);
  array upper (10) _temporary_ (35:44);
  do i=1 to dim(tert);
    tert(i)= (pa_avg >= lower(i)/10) + (pa_avg > upper(i)/10);
  end;
  drop i;
run;

 

Contributor
Posts: 25

Re: Nested do loop tertiles

Thanks Tom! That's extremely helpful; I would have never thought to do it that way. I appreciate it!

☑ This topic is solved.

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

Discussion stats
  • 8 replies
  • 210 views
  • 0 likes
  • 4 in conversation