DATA Step, Macro, Functions and more

Nested if - do loops

Accepted Solution Solved
Reply
Contributor
Posts: 65
Accepted Solution

Nested if - do loops

I have a dataset which looks like this:

ID      2017    2018    2019    2020

2017    30      24      20      18
2018    30      24      20      18
2019    30      24      20      18
2020    30      24      20      18

I am looking to create an array based on a few inputs:

%let FixedorFloating = '1 or 0';
%let Repricingfrequency = n Years;
%let LastRepricingDate = 'Date'n;

So far my code looks like this:

data ReferenceRateContract;
set refratecontract;

*arrays for years and flags;
array _year(2017:2020) year2017-year2020;
array _flag(2017:2020) flag2017-flag2020;

*loop over array;

if &FixedorFloating=1;

    do i=&dateoflastrepricing to hbound(_year);
    /*check if year matches year in variable name*/
    if put(ID, 4.) = compress(vname(_year(i)),, 'kd') 
        then _flag(i)=1;
    else _flag(i)=0;

    end;

else if &fixedorfloating=0;

    do i=&dateoflastrepricing to hbound(_year);
    if put (ID,4.)<=compress(vname(_year(i)),,'kd')
        then _flag(i)=1;

        else if put (ID, 4.) = compress(vname(_year(i-2*i)),, 'kd') 
        then _flag(i)=1;

        else _flag(i)=0;
        end;

drop i;

run;

The code works for the original if function but I'd like to make this more dynamic by introducing the else if FixedorFloating=0.

I'm also looking to make my function able to decipher whether the ID is on a year +2i year from the ID. i.e.

if ID=2017 - i'd like a 1 for years 2017, 2019. For ID=2018, 
I'd like a 1 for 2018, 2020 and so on hence the 

year(I-2*I)

I'm unsure if this is reasonable or incorrect.

The error of the log looks like this:

82         else if &fixedorfloating=0;
         ____
         160
 ERROR 160-185: No matching IF-THEN clause.

 84         then do i=&dateoflastrepricing to hbound(_year);
          ____
          180
 ERROR 180-322: Statement is not valid or it is used out of proper order.


 91         else _flag(i)=0;
 92         end;
           ___
           161
 ERROR 161-185: No matching DO/SELECT statement.

I'm assuming the if do followed by an else-if do isn't structured properly.


Accepted Solutions
Solution
‎03-05-2018 05:03 AM
Super User
Posts: 9,886

Re: Nested if - do loops

An if statement like this:

if &FixedorFloating=1;

(if without a then)

is called a "subsetting if", it is standalone, and does not support an else clause.

I guess you wanted something along:

data ReferenceRateContract;
set refratecontract;

*arrays for years and flags;
array _year(2017:2020) year2017-year2020;
array _flag(2017:2020) flag2017-flag2020;

*loop over array;

if &FixedorFloating=1
then do i=&dateoflastrepricing to hbound(_year);
    /*check if year matches year in variable name*/
  if put(ID, 4.) = compress(vname(_year(i)),, 'kd') 
  then _flag(i)=1;
  else _flag(i)=0;
end;
else if &fixedorfloating=0
then do i=&dateoflastrepricing to hbound(_year);
  if put (ID,4.)<=compress(vname(_year(i)),,'kd')
  then _flag(i)=1;
  else if put (ID, 4.) = compress(vname(_year(i-2*i)),, 'kd') 
  then _flag(i)=1;
  else _flag(i)=0;
end;
drop i;
run;
---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
How to convert datasets to data steps
How to post code

View solution in original post


All Replies
Solution
‎03-05-2018 05:03 AM
Super User
Posts: 9,886

Re: Nested if - do loops

An if statement like this:

if &FixedorFloating=1;

(if without a then)

is called a "subsetting if", it is standalone, and does not support an else clause.

I guess you wanted something along:

data ReferenceRateContract;
set refratecontract;

*arrays for years and flags;
array _year(2017:2020) year2017-year2020;
array _flag(2017:2020) flag2017-flag2020;

*loop over array;

if &FixedorFloating=1
then do i=&dateoflastrepricing to hbound(_year);
    /*check if year matches year in variable name*/
  if put(ID, 4.) = compress(vname(_year(i)),, 'kd') 
  then _flag(i)=1;
  else _flag(i)=0;
end;
else if &fixedorfloating=0
then do i=&dateoflastrepricing to hbound(_year);
  if put (ID,4.)<=compress(vname(_year(i)),,'kd')
  then _flag(i)=1;
  else if put (ID, 4.) = compress(vname(_year(i-2*i)),, 'kd') 
  then _flag(i)=1;
  else _flag(i)=0;
end;
drop i;
run;
---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
How to convert datasets to data steps
How to post code
Contributor
Posts: 65

Re: Nested if - do loops

Posted in reply to KurtBremser

Perfect, thanks.

 

Just trying to figure out a way to make the do loop flag up ID = year+2i now.

 

I get this error:

 

 ERROR: Array subscript out of range at line 87 column 43.

 

Looking to pair up based on the following:

 

If ID = 2017, flag 2017, 2019

if ID= 2018, flag 2018, 2020

if ID= 2019, flag 2019

if ID= 2020, flag 2020

 

Contributor
Posts: 65

Re: Nested if - do loops

Found it, just had to extend the array with appropriate variables. Ty.

☑ This topic is solved.

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

Discussion stats
  • 3 replies
  • 95 views
  • 0 likes
  • 2 in conversation