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

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)

bsp.GIF

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

1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

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?

View solution in original post

13 REPLIES 13
arodriguez
Lapis Lazuli | Level 10
Its not necessary to do an array, you could use the max function.
max(jan1,jan2,feb1,..);
Sandra_L
Calcite | Level 5

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...

 

 

ballardw
Super User

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.

Sandra_L
Calcite | Level 5
i have the precipitaion data for a lot of station and i want to generate areas with the same seasonal prec patterns. so i trie to find out the time when the maximum rain in spring and autumn falls.
see at my answere above what i imagine as result... the Lag Function i first have to explore...
Astounding
PROC Star

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?

 

Sandra_L
Calcite | Level 5

totaly right! thats the next competition, so far i have no idea 😉

Sandra_L
Calcite | Level 5
well jan1, i need to compare to dec2 of the previous year, but each year i a different observation...
Astounding
PROC Star

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?

Sandra_L
Calcite | Level 5

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;

 

Astounding
PROC Star

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.

Sandra_L
Calcite | Level 5
easy, thanks! for the jan1 problem i got the tip to try it with RETAIN SATEMENT... don't know jet, but i will find out 🙂
chears,
Sandra
Astounding
PROC Star

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.

Sandra_L
Calcite | Level 5
works perfect with lag for the previous obs! yeah!

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 13 replies
  • 1641 views
  • 1 like
  • 4 in conversation