PatternMatching
PatternMatching

Reputation: 466

Sum of values between start and end date in MATLAB

If, in MATLAB, I have a set of start and end dates that represent a contiguous period of time, how would I take a separate daily time series and accumulate any values from said time series over each start/end pair?

Is this something that can be done with accumarray()? It wasn't clear to me whether it would be efficient to construct the vector that groups each element of the time series by start/end pair.

Inputs

Start Date    End Date

01/01/12      01/31/12
02/01/12      02/28/12
...

Date          Value

01/01/12      23
01/02/12      87
01/03/12      5
01/04/12      12
...
02/01/12      4

Output

Start Date    End Date    Value

01/01/12      01/31/12    127
02/01/12      02/28/12    4
...

Upvotes: 3

Views: 894

Answers (3)

H.Muster
H.Muster

Reputation: 9317

For consecutive periods of time, the following approach might work. Note that the strings containing dates are cellstrings and, for consecutive data, only the first column of your start date /end date matrix is necesssary.

Furthermore, note that I separated your time series data into two variables for the sake of clarity.

dateBins = {...
    '01/01/12';
    '02/01/12';
    '03/01/12';
    '04/01/12'};

dates = {
    '01/01/12'
    '01/02/12'
    '01/03/12'
    '01/04/12'
    '02/01/12'    };

values = [
    23
    87
    5
    12
    4];

With these variables, the following code

[thrash, idx] = histc(datenum(dates), datenum(dateBins))

accumVal = accumarray(idx, values);

result = zeros(length(dateBins), 1); 
result(1:length(accumVal),1) = accumVal;

will result in:

result =

   127
     4
     0
     0

Upvotes: 3

Chris
Chris

Reputation: 1531

I would iterate over each pair of start/end dates. Then pick out the index start/stop pairs and sum them. If you use datestrs, you can make the following less brittle, while allowing for more flexibility in how you represent times that cross years, etc.

start_date = {'01/01/12'};
end_date={'01/31/12'};
datevec={'01/01/12','01/02/12','01/03/12','01/31/12'};
values=[23,87,5,12];

for i=1:numel(start_date)

    is = find(ismember(datevec,start_date{i})==1);
    ie = find(ismember(datevec,end_date{i})==1);

    sum(values(is:ie))

end

Upvotes: 1

Dennis Jaheruddin
Dennis Jaheruddin

Reputation: 21563

Assuming you have already got two vectors with the start dates and end dates in a format that you can use to compare and you just want to count how many occurrences there are in each cateogory, then it is quite straightforward:

% Your data
Dates = 25*rand(10,1);
StartDate = [1 10 20];
EndDate = [9 19 29];

% The Calculation
Result = zeros(size(StartDate)); %Initialization
for d = 1:length(startdate)
    idx = dates >= StartDate & dates <= EndDate;
    Result(d) = sum(idx);
end

Note that this will require that you store your dates in a comparable format.

Upvotes: 1

Related Questions