I'm assuming your Ids are positive integers and and your Dates are numbers.
If you wanted the maximum Date for each Id, it would be a perfect case for accumarray
with the max
function. In the following I'll use f
to denote a generic function passed to accumarray
.
The fact that you want the index of the maximum makes it a little trickier (and more interesting!). The problem is that the Dates corresponding to a given Id are passed to f
without any reference to their original index. Therefore, an f
based on max
can't help. But you can make the indices "pass through" accumarray
as imaginary parts of the Dates.
So: if you want just one maximizing index (even if there are several) for each Id:
result = accumarray(t.Id,... %// col vector of Id's
t.Date+1j*(1:size(t,1)).', ... %'// col vector of Dates (real) and indices (imag)
[], ... %// default size for output
@(x) imag(x(find(real(x)==max(real(x))),1))); %// function f
Note that the function f
here maximizes the real part and then extracts the imaginary part, which contains the original index.
Or, if you want all maximizing indices for each Id:
result = accumarray(t.Id,... %// col vector of Id's
t.Date+1j*(1:size(t,1)).', ... %'// col vector of Dates (real) and indices (imag)
[], ... %// default size for output
@(x) {imag(x(find(real(x)==max(real(x)))))}); %// function f
If your Ids are strings: transform them into numeric labels using the third output of unique
, and then proceed as above:
[~, ~, NumId] = unique(t.Id);
and then either
result = accumarray(NumId,... %// col vector of Id's
t.Date+1j*(1:size(t,1)).', ... %'// col vector of Dates (real) and indices (imag)
[], ... %// default size for output
@(x) imag(x(find(real(x)==max(real(x))),1))); % function f
or
result = accumarray(NumId,... %// col vector of Id's
t.Date+1j*(1:size(t,1)).', ... %'// col vector of Dates (real) and indices (imag)
[], ... %// default size for output
@(x) {imag(x(find(real(x)==max(real(x)))))}); %// function f