Reputation: 123
Hello I have cell array of repeating strings and numbers(class double) corresponding to the strings.
Name Score
'John' 90
'Mat' 99
'John' 98
'Tonny' 88
'Carl' 99
'Rem' 88
'Tonny' 99
How do I count the number of times the same name appears and the total score they got. For instance the total score for 'John' would be 188. I know you can use unique function to do it, but is there other way to do it beside using unique. It would be great if you guys could help me out.
Thank you.
Upvotes: 0
Views: 148
Reputation: 271
Had a similar problem recently and found accumarray
. I did not test it with a cell vector directly but it definitely works for numerical values and does exactly what you want.
names = [1,2,1,3,4,5,3]
scores = [90, 99, 98, 88, 99, 88, 99]
counts = accumarray(names,scores)
Upvotes: 0
Reputation: 36710
Here is a solution using accumarray
names = {'John', 'Mat', 'John', 'Tonny', 'Carl', 'Rem', 'Tonny'}
scores = [90, 99, 98, 88, 99, 88, 99]
[uniquenames,b,c]=unique(names,'stable')
counts = accumarray(c,scores)
Upvotes: 0
Reputation: 112669
I would go with unique
and accumarray
. But if you want to avoid unique
, you can do it this way:
% // Data:
data = { 'John' 90
'Mat' 99
'John' 98
'Tonny' 88
'Carl' 99
'Rem' 88
'Tonny' 99}
%// Generate unique numeric labels without `unique`
N = size(data,1);
[ii, jj] = ndgrid(1:N);
[~, ind] = max(triu(reshape(strcmp(data(ii,1), data(jj,1)), N, N)));
ind = ind([true diff(ind)>0]);
%// Apply `accumarray` to that:
s = accumarray(ind(:), [data{:,2}].', [], @sum, NaN);
ind = ind([true diff(ind)>0]);
result = [data(ind,1) num2cell(s(~isnan(s)))];
In this example,
result =
'John' [188]
'Mat' [ 99]
'Tonny' [187]
'Carl' [ 99]
'Rem' [ 88]
Upvotes: 2
Reputation: 1252
Your answer will depend on how the data is stored.
IF the names are stored in a cell array and the scores are stored as a vector you can do the following:
names = {'John', 'Mat', 'John', 'Tonny', 'Carl', 'Rem', 'Tonny'}
scores = [90, 99, 98, 88, 99, 88, 99]
ref_mat = cellfun(@(x) strcmp(names,x),names,'UniformOutput',false)
tot_score = cellfun(@(x) sum(scores(x)), ref)
Here you will create a index mat of matching names, then reference those scores and sum them. The total scores will be with respect to each name, so repeated names will have repeated totals. In this way you do not have to find unique values.
Upvotes: 1