Hi folks!
I have a time series of precipitation data for 30 years (jahre) for a lot of stations (idgem). Each year has a value for a half month step like this (jan1,..., dec2)
Now I want to find out the local maxima in the way that the values are kept, if they are bigger than the previous and the next. I tried it this way
data test3;
set test2;
array maxi [24] jan1 jan2 feb1 feb2 mar1 mar2 apr1 apr2 may1 may2 jun1 jun2
jul1 jul2 aug1 aug2 sep1 sep2 oct1 oct2 nov1 nov2 dec1 dec2;
do i=1 to 24;
if maxi [i-1] < maxi [i]> maxi [i+1] then maxi [i] = maxi [i];
else maxi [i]=.;
end;
run;
I always get an error message "Array subscript out of range ".
Any ideas how I can tell SAS to compare wiht the previous and next value and keep the compared value if it is bigger? And how do I compare the value for example of jan1 of 1961 to dec2 of 1960?
Thanks a lot,
Sandra
Here's one approach. You can always decide later what to do with the original numeric values.
data want;
set have;
array local {24} $ 1;
do _n_=1 to 24;
local{_n_} = 'N';
end;
array maxi {24} /* same variables as before */;
do _n_=2 to 23;
if (maxi{_n_-1} < maxi{_n_}) and (maxi{_n_} > maxi{_n_+1}) then local{_n_}='Y';
end;
run;
Of course, you still have to contend with the endpoints (JAN1 and DEC2) as well as plateaus. For example, what should happen if the pattern is 15, 18, 18, 15?
Hey,
but the max function gives me just one maximal value. Whar´t i want are local maxima, compared to the previous and next value
For example as input:
jan1 jan2 feb1 feb2 mar1 mar2 apr1 apr1
1960 20 25 19 20 25 30 25 20
as output i want:
jan1 jan2 feb1 feb2 mar1 mar2 apr1 apr1
1960 25 30
so just the values that are bigger then the previous ant next value are left...
If you are trying to find a maximum Value then
maxValue = max(of Maxi(*));
If you want to know the first occurence of that maximum:
MaxPos = whichn(MaxValue,of Maxi(*));
LAG is the traditional function for examining values of variables on previous observations of a data set.
You would have to provide more details as to what you are attempting with the look back to get a more complete example.
Lag(Dec2) would give you the value of Dec2 from the previous record though there are some issues about the presence of Lag in IF constructs.
So it sounds like you want to keep multiple local maxima.
How do you want to handle JAN1 > JAN2? Would JAN1 be a local maximum?
What about DEC2 when DEC1 < DEC2?
totaly right! thats the next competition, so far i have no idea 😉
Here's one approach. You can always decide later what to do with the original numeric values.
data want;
set have;
array local {24} $ 1;
do _n_=1 to 24;
local{_n_} = 'N';
end;
array maxi {24} /* same variables as before */;
do _n_=2 to 23;
if (maxi{_n_-1} < maxi{_n_}) and (maxi{_n_} > maxi{_n_+1}) then local{_n_}='Y';
end;
run;
Of course, you still have to contend with the endpoints (JAN1 and DEC2) as well as plateaus. For example, what should happen if the pattern is 15, 18, 18, 15?
Hi!
This works so far. i added something to take into account the plateaus but i dont get how to tell SAS to take the original values instead of the 'Y'.
For takin into account the jan1 (dec2) problem i shoult add tomething like:
if maxi [_n_] > (maxi [_n_-1] where jahr=jahr-1) then local [_n_] = 1;
looks like this now:
data test3;
set test2;
array local [24];
do _n_=1 to 24;
local[_n_] = 0 ;
end;
array maxi [24] jan1 jan2 feb1 feb2 mar1 mar2 apr1 apr2 may1 may2 jun1 jun2
jul1 jul2 aug1 aug2 sep1 sep2 oct1 oct2 nov1 nov2 dec1 dec2;
do _n_=2 to 23;
if (maxi [_n_-1] < maxi [_n_]) and (maxi [_n_]> maxi [_n_+1]) then local [_n_] = 1;
if maxi [_n_] = maxi [_n_-1] then local [_n_] = 1;
if maxi [_n_] = maxi [_n_+1] then local [_n_] = 1;
end;
do _n_=1; /* same for 24 */
if maxi [_n_] > maxi [_n_-1] /* here take the value from a line above or year (jahr) bevore*/ then local [_n_] = 1;
if maxi [_n_] > maxi [_n_+1] then local [_n_] = 1;
if maxi [_n_] = maxi [_n_+1] then local [_n_] = 1;
end;
run;
Here's a strategy to take the original values instead of "Y".
Keep the LOCAL array numeric (as you have now done), but don't set the values to 0. Leave them missing.
Instead of setting LOCAL array elements to 1, set them to the same element of the MAXI array. When you're done, the LOCAL array will contain all the local maxima, with missing values for the non-maxima.
For the JAN1 problem, I think you will need this statement:
prior_dec2 = lag(dec2);
RETAIN will run into problems, since each observation replaces the previous DEC2 value with a new value.
Good luck.
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.