2

how to count unique elements of a cell in matlab? the a above code will count the number of characters in a cell I liked this

[uniqueC,~,idx] = unique(characterCell); %# uniqueC are unique entries in c
%# replace the tilde with 'dummy' if pre-R2008a
counts = accumarray(idx(:),1,[],@sum);  

but the broblem is: my cell contains alphabet letters from a to e. I want to find no of 'a's 'b's...... this code will not tell that there is e.g. zero 'e's if it is not available. simply there will be 4 counts instead of 5

1
2
2
3

and not

1
2
2
3
0

How can I add

     a=1
     b=2......
Community
  • 1
  • 1
pac
  • 291
  • 9
  • 19

2 Answers2

4

You can use ISMEMBER instead of UNIQUE to solve this:

characterCell = {'a' 'b' 'b' 'a' 'b' 'd' 'c' 'c'};  %# Sample cell array
matchCell = {'a' 'b' 'c' 'd' 'e'};                  %# Letters to count

[~,index] = ismember(characterCell,matchCell);  %# Find indices in matchCell
counts = accumarray(index(:),1,[numel(matchCell) 1]);  %# Accumulate indices

And you should get the following for counts:

counts =

     2
     3
     2
     1
     0

EDIT:

If I understand your comment correctly, it sounds like you want to store or display the letters together with their number of occurrences. One way to do this is to collect them together into a 5-by-2 cell array by first converting counts into a cell array using NUM2CELL:

>> results = [matchCell(:) num2cell(counts)]

results = 

    'a'    [2]
    'b'    [3]
    'c'    [2]
    'd'    [1]
    'e'    [0]

Or you could create a character array to display them by converting counts to a string using NUM2STR:

>> results = strcat(char(matchCell(:)),':',num2str(counts))

results =

a:2
b:3
c:2
d:1
e:0
gnovice
  • 125,304
  • 15
  • 256
  • 359
  • but it is not working [uniqueC,~,idx] =ismember(Allquants{1},{'a','b','c','d','e'}); counts = accumarray(index(:),1,[5 1]) ??? Error using ==> cell.ismember Too many output arguments. – pac Sep 01 '11 at 21:19
  • 1
    @pac: Look at the code I posted above. You can't just swap out the function names, you have to change how the output is handled too. – gnovice Sep 01 '11 at 21:20
  • done:>> str= num2cell(Allquants{1}) [~,index] =ismember(str,{'a','b','c','d','e'}); counts = accumarray(index(:),1,[5 1]) – pac Sep 01 '11 at 21:25
  • @pac: If `Allquants{1}` is already a cell array of letters, then you don't need NUM2CELL. I only used that in my previous example to easily create a cell array from a character string (less typing). – gnovice Sep 01 '11 at 21:32
  • Can I ask another question? I want also the letters added in the vector count. I thought of doing a loop if index 1 then 'a' and so on but I think there is an easier way for sure. I am learning Matlab by projects and want to learn it in a prof way. Thanks so much. By the way it is a great site/forum – pac Sep 02 '11 at 17:50
2

You can append all the possible characters to the cell array when calling the UNIQUE function so that you get at least one occurrence of each, then we simply subtract 1 from all counts returned by ACCUMARRAY.

Example:

characterCell = {'a' 'b' 'b' 'a' 'b' 'd' 'c' 'c'};

allPossibleChars = {'a' 'b' 'c' 'd' 'e'};  %# list of all possible characters
c = [characterCell allPossibleChars];      %# make sure all chars are represented
[uniqueC,~,idx] = unique(c);
counts = accumarray(idx(:),1,[],@sum) - 1; %# subtract one from occurrences

The result:

>> counts
counts =
     2
     3
     2
     1
     0
Amro
  • 123,847
  • 25
  • 243
  • 454
  • @pac: by adding all possible characters ('a' to 'e'), you ensure that they are all represented in your data. Then we use the same code you had to count how many times each occur. Finally we have to subtract 1 from the counts to account for the characters we initially added.. – Amro Sep 03 '11 at 19:43
  • i want to expand the function let us say the cell contains also zeros. If i use 1 '0' the answer of count will be the same with additional row for the no of zeros= 1 in this case. How to make it neglect numbers? – pac Mar 03 '12 at 20:52