turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

Find a Community

- Home
- /
- SAS Programming
- /
- Base SAS Programming
- /
- find maximum in time series with arrey loop

Topic Options

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-10-2016 11:07 AM - edited 05-10-2016 11:10 AM

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

Accepted Solutions

Solution

05-11-2016
09:58 AM

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-10-2016 11:52 AM

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?

All Replies

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-10-2016 11:14 AM

Its not necessary to do an array, you could use the max function.

max(jan1,jan2,feb1,..);

max(jan1,jan2,feb1,..);

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-10-2016 11:29 AM

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

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-10-2016 11:18 AM

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.

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-10-2016 11:39 AM

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

see at my answere above what i imagine as result... the Lag Function i first have to explore...

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-10-2016 11:25 AM

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?

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-10-2016 11:31 AM

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

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-10-2016 11:53 AM

well jan1, i need to compare to dec2 of the previous year, but each year i a different observation...

Solution

05-11-2016
09:58 AM

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-10-2016 11:52 AM

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?

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-11-2016 08:43 AM - edited 05-11-2016 08:51 AM

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;

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-11-2016 09:00 AM

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.

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-11-2016 10:01 AM

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

chears,

Sandra

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-11-2016 10:12 AM

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.

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-11-2016 11:56 AM

works perfect with lag for the previous obs! yeah!