BookmarkSubscribeRSS Feed
Swordfish
Calcite | Level 5

Hi,

I have 400 or more variables in the data set. For the illustration purpose I am limiting my data code to only 11 variables.

The issue is I want to create a variable “DF” based on the next two months balance. If the Balance/amount drops below 9 in any of the next two months the variable “ DF” gets “Y” else “N”.

I provide below the data I have and the data I want and the code that generates error.

Sas data creation:

Data months;

  input m1 m2 m3 m4 m5 m6 m7 m8 m9 m10 m11;

  datalines;

  20  20    50    50    2     30    5     100   100   40    40

  ;

  run;

Data I_wana_hav;

Input DF1 $ m1 DF2 $ m2 DF3 $ m3 DF4 $ m4 DF5 $ m5 DF6 $ m6 DF7 $ m7 DF8 $ m8 DF9 $ m9 DF10 $ m10 DF11 $ m11;

Datalines;

N 20 N 20 N 50 Y  50 Y 2 Y 30 Y 5 N 100 N 100 N 40 N  40

;

run;

/*code generates error*/Data test1;

set months;

array Am{*} m1-m11;

array ADF{*} $ DF1-DF11;

do j=1 to dim(AM);

do i=1 to 2;

if Am(j+i)<9 then ADF{j}="y";

else ADF{j}="N";

end;

end;

run;

Any help would be highly appreciated.

Thanks in advance

5 REPLIES 5
Tom
Super User Tom
Super User

The bounds for your inner loop should be J+1 and DIM(AM).  (or you could make the upper bound for your outer loop DIM(ADF)-2 )

do j=1 to dim(ADF);

  ADF(j)= 'N';

  do i=j+1 to min(J+2,dim(AM));

    if AM(i)<9 then ADF(j)="Y";

  end;

end;

Swordfish
Calcite | Level 5

Thank you Tom. This really helped a lot.

God Bless you.

MikeZdeb
Rhodochrosite | Level 12

Hi ... I think that the two loops might make this more complicated than necessary.

data test1;

set months;

array m(11);

array df(11) $1 (11*'N');

do _n_ = 1 to 9;

  df(_n_) = ifc(m(_n_+1) lt 9 or m(_n_+2) lt 9 , 'Y', 'N');

end;

run;

you could use the asterisks and dim function in the above, but unless you do something previous to the data step to figure out how many

variables you are checking, you'll have to hard code the dimension of DF ... so why bother with the asterisks and dim function in your code ...

array Am{*} m1-m11;

array ADF{*} $ DF1-DF11;

do j=1 to dim(AM);

ballardw
Super User

MikeZdeb wrote:

you could use the asterisks and dim function in the above, but unless you do something previous to the data step to figure out how many

variables you are checking, you'll have to hard code the dimension of DF ... so why bother with the asterisks and dim function in your code ...

array Am{*} m1-m11;

array ADF{*} $ DF1-DF11;

do j=1 to dim(AM);


Use of the DIM() makes it easier to keep the code working if you change the size of the array. For example suppose some requests a similar logic based on biweekly periods. Once the variables are assigned/created you don't have to remember to adjust the boundary on the loop.

If you get to multiple nested loops you can really appreciate that feature.

MikeZdeb
Rhodochrosite | Level 12

Hi ... in this instance, you are talking about one line of code that follows several  lines that already require editiing as the array size changes.  If one wants to fix this example, you are better off with a macro variable that adjusts both arrays and the loop.

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

How to Concatenate Values

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 5 replies
  • 1430 views
  • 0 likes
  • 4 in conversation