I am using the accumarray function to sum the values in vector "data" within categories defined by the vector "id". I want my vector id to not be necessarily sorted, and also potentially containing non-consecutive numbers. I also want to end up with a vector of sums Sij that is the same size of id (rather than the same size of unique(id)).
For instance
id = [3 2 4 3 2 3]';
data = [6 43 3 4 2 5]';
As an output I want
Sij = [15 45 3 15 45 15]';
I managed to do it by creating datasets and use the join function (using the following code), but I was wondering if there's a more efficient way (this is part of a likelihood function I am maximizing and I'd like to speed it up). Thanks!
clear;
id = [3 2 4 3 2 3]';
data = [6 43 3 4 2 5]';
indices = [id ones(size(id))];
S = accumarray(indices, data);
DS = dataset((1:size(S))',S);
DS = DS(DS.S~=0,:);
DS.Properties.VarNames={'id','S'};
C =join(dataset(id),DS);
Sij = C.S;
You basically need to replicate the output of
accumarray
. The replication pattern is given by the third output ofunique
:Another possibility: use
bsxfun
to detect equal values ofid
, and then matrix multiplication to accumulate the corresponding values ofdata
:Test to see which approach is fastest for you.