calculate the accumulation of a variable over time within a loop?

Hello,
I have evaporation as daily values (m). I have calculated the weighted fieldmean, which gives me a vector with length = no. of days. However, I would like to display these values as monthly sums.
How can I do this in a loop?
For example:
newsum(1) = nansum(data(1:30)) and so forth...

2 Comments

Do you have a corresponding date/day of month vector or does the series simply begin at a known date? And, of course, year to know if leap year or not...
it starts in 1993 1st January and ends 2010 31st December, i'm not sure how to do it other than every 30 days..

Sign in to comment.

 Accepted Answer

Once you get the month data, the code will be almost identical to this answer:
Instead of @std, you'll want to pass in @sum

6 Comments

Thanks, Sean! although I get Y & M = 0 when I change the code like such:
[Y,M] = datevec(data);
[a,~,c] = unique([Y,M],'rows');
out = [a, accumarray(c,data,[],@(x)sum(x))];
I have no idea what any of this code means
Break it into small pieces and use the doc :)
Note, this is an advanced maneuver, but once you get your head around it, you'll find uses for it that you never would've imagined.
Here's what's going on:
datevec gives us year and month
unique gives us unique year/month combos in a and c is the index of each year month combo into the unique ones. I.e. which unique combo is each element in c.
accumarray uses c to figure out which groups to bin and applies the operation (sum) to the corresponding elements of c in data.
For more info:
doc unique
doc accumarray
...I get Y & M = 0 when I ...
If the data vector you pass to datevec isn't either a Matlab datenum or date string, then of course the output won't be meaningful.
In the previous response to my query you say the data span from Jan 1, 1993, thru 2010. So, generate a date vector for that range to use...
>> dn=[datenum(1993,1,1):datenum(2010,12,31)].';
>> [datestr(dn(1));datestr(dn(end))]
ans =
01-Jan-1993
31-Dec-2010
>> length(dn)
ans =
6574
>>
That should be the same length as the number of entries in your data vector.
I have read the documents but I can't seem to find a way of increasing the interval to 3 or 6 months, is there a way to do this?
I have realised it makes more sense to calculate 3-month sums..I know how to do this the long way but wondered if I can modify this function

Sign in to comment.

More Answers (1)

... to calculate 3-month sums...
There it's simpler to use another Matlab "trick" of recognizing and utilizing internal storage order and Matlab's handling of arrays. Generate the vector of monthly sums as above then to group by threes reshape and sum over the reshaped array and recast back...
mnthsum=accumarray(... % the monthly sums as above
threemnth=sum(reshape(mnthsum,3,[])).'; % sum over columns of 3 row/each
The above relies on the linear storage order and that Matlab orders arrays/matrices in column-major order and the default action of functions such as sum is to operate over columns. This "trick" is useful for any such operation over a given evenly-divisible subset of any array.
ADDENDUM
If it's decided that the monthly sums aren't needed any longer, the above can be done in place, of course...
mnthsum=sum(reshape(mnthsum,3,[])).';

Asked:

on 17 Sep 2014

Edited:

dpb
on 17 Sep 2014

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!