Yi.
Yi.

Reputation: 525

how can I aggregately accumulate a cell array?

Say that I have:

A = {'a.java' 1;'a.java' 2; 'b.java' 1; 'b.java' 0; 'a.java' 4; 'c.java' 6};

I would like to accumulate the second column numbers based on the first column similarity.

I want to get:

B = {'a.java' 1+2+4; 'b.java' 1+0; 'c.java' 6}

How can I achieve that?

Many thanks,

Upvotes: 5

Views: 768

Answers (3)

gnovice
gnovice

Reputation: 125854

You can easily do this without a for loop using the functions UNIQUE and ACCUMARRAY:

>> [uniqueValues,~,index] = unique(A(:,1));
>> B = [uniqueValues num2cell(accumarray(index,[A{:,2}]))]

B = 

    'a.java'    [7]
    'b.java'    [1]
    'c.java'    [6]

Upvotes: 6

ilalex
ilalex

Reputation: 3078

Something like this:

[a b c] = unique({A{:,1}});
for i=1:length(a)
    B{i, 1} = a(i);
    B{i, 2} = sum([A{find(c==i), 2}]);
end

Upvotes: 3

arne.b
arne.b

Reputation: 4330

Find the unique keys in A (the unique function can conventiently return a mapping from the keys in A to the entry in the unique key set), then iterate over these.

[u,i1,i2]=unique(A(:,1));     % i1 is not needed, actually
Avalues = cell2mat(A(:,2));   % convert numerical part of cell array to matrix
for i=1:max(i2)
    u{i,2}=sum(Avalues(i2==i));
end

This can also be extended to work column-wise on multiple data columns in the cell array.

Upvotes: 3

Related Questions