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;
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;
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_;
Objects 1 and 2 have 5 times and you only allow for 4 in array price2.
PG
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
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
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;
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;
Thank you all for helping me with this problem.
HHC
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;
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;
You Say MOVING Maximum and Minimum.
Can you post the required OUTPUT of the data set, HAVE?
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.