BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
hhchenfx
Rhodochrosite | Level 12

Hi,

I try to do the moving Highest and Lowest of price for each object using this array approach.

Somehow I got the error "Array subscript out of range ..."

Could you help me to correct it?

Thank you,

HHC

data have;

  input object time price level;

  datalines;

1 1     5     9

1 2     2     3

1 3     8     5

1 4     10    25

1 5     12    63

2 1     15     29

2 2     12     3

2 3     18     15

2 4     10    15

2 5     18    6

3 1     15     29

3 2     22     32

3 3     8     52

3 4     11    50

3 100     1200    6

;run;


data want2;
array price2(4) _temporary_;

kk=0;

do until (last.object);
set have;
by object;
kk+1;
price2(kk)=price;
end;

max_record=kk;
nn=0;

do until (last.object);
set have;
by object;
nn+1;
highest=0;
lowest=10000;

do i=nn+1 to max_record;
  if price2(i)>highest then highest=price2(i);
  if price2(i)<lowest then lowest=price2(i);
end;
end;
run;

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

So the third DO loop is where you are checking for the MIN/MAX so that is what you need to modify.

data want2;

  array price2(1000) _temporary_;

* Load Array for current BY GROUP ;

  do max_record=1 by 1 until (last.object);

    set have;

    by object;

    price2(max_record)=price;

  end;

* Loop Over Current BY GROUP ;

  do nn=1 by 1 until (last.object);

    set have;

    by object;

* Find min and max over current and three previous values for this by group ;

    highest=.;

    lowest=constant('big');

    do i=max(1,nn-3) to nn ;

      highest=max(highest,price2(i));

      lowest=min(lowest,price2(i));

    end;

* Write the value out;

    output;

  end;

run;

View solution in original post

10 REPLIES 10
Tom
Super User Tom
Super User

Because you set the size of your temporary array too small.  You set it to 4 and the first group has 5 records.

You should just set it to something really large.

array price2(1000) _temporary_;

PGStats
Opal | Level 21

Objects 1 and 2 have 5 times and you only allow for 4 in array price2.

PG

PG
hhchenfx
Rhodochrosite | Level 12

oh, what I want to do is to get the Max and Min value for the prior 4 record.

That's why I give the price2(4).

So it look like there is no way to do that moving Min/Max with array?

HHC

PGStats
Opal | Level 21

Yes it can be done with an array, combined with the MOD function:

data want;

array p{0:3} _temporary_;

set have; by object;

if first.object then call missing(of p{*});

p{mod(_n_,4)} = price;

lowest = min(of p{*});

highest = max(of p{*});

run;

PG

PG
Patrick
Opal | Level 21

Because you write "prior 4" the one thing you might need to change on 's code is the time/sequence when you assign the current value of "price" - change as done below.

data want;

array p{0:3} _temporary_;

set have; by object;

if first.object then call missing(of p{*});

lowest = min(of p{*});

highest = max(of p{*});

p{mod(_n_,4)} = price;

run;


Tom
Super User Tom
Super User

So the third DO loop is where you are checking for the MIN/MAX so that is what you need to modify.

data want2;

  array price2(1000) _temporary_;

* Load Array for current BY GROUP ;

  do max_record=1 by 1 until (last.object);

    set have;

    by object;

    price2(max_record)=price;

  end;

* Loop Over Current BY GROUP ;

  do nn=1 by 1 until (last.object);

    set have;

    by object;

* Find min and max over current and three previous values for this by group ;

    highest=.;

    lowest=constant('big');

    do i=max(1,nn-3) to nn ;

      highest=max(highest,price2(i));

      lowest=min(lowest,price2(i));

    end;

* Write the value out;

    output;

  end;

run;

hhchenfx
Rhodochrosite | Level 12

Thank you all for helping me with this problem.

HHC

stat_sas
Ammonite | Level 13

data want(keep=object min max);

     array p(50) _temporary_;

     do _n_=1 by 1 until (last.object);

           set have;

           BY object;

           p(_n_)=price;

     end;

     max=max(of p(*));

     min=min(of p(*));

run;

Ksharp
Super User

You could assign a condition when you give a price to array.

do until (last.object);

set have;

by object;

kk+1;

if kk le 4 then price2(kk)=price;

end;

KachiM
Rhodochrosite | Level 12

You Say MOVING Maximum and Minimum.

Can you post the required OUTPUT of the data set, HAVE?

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!

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
  • 10 replies
  • 3761 views
  • 9 likes
  • 7 in conversation