Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

how to get the most repeated element of a cell array?

Asked by effess on 26 Apr 2013

i have an cell array like this

 {[];[];[];[];[];[];[];[];'rj';'rj';'rj';'rj';'rj';'rj';'rj';'rj';'rj';'rj';'rj';'rj';'rj';'rj';}

is there a way to get the label of this array as rj?

3 Comments

Cedric Wannaz on 26 Apr 2013

Is the content either empty or equal to the same string? What happens if there are more empty cells than cells containing strings?

Matt J on 26 Apr 2013

maybe i did ask the question wrong, but if i have more {''} it will give me that name. instead i want {'rj'}. is there a workaround to counting?

Yes, you'll need to clarify the question. Why should {''} be ignored? Are there any other strings that should be ignored?

the cyclist on 26 Apr 2013

In other words, you need to provide a more precise definition of the rule that defines the label.

effess

Products

2 Answers

Answer by Cedric Wannaz on 26 Apr 2013
Edited by Cedric Wannaz on 26 Apr 2013
Accepted answer

the cyclist >> I knew I had overlooked something easier. :-)

Well, look at how I did overlook something easier ;-D :

 C = {[];[];[];[];[];[];[];[];'rj';'rj';'rj';'ab';'ab'} ;
 setMatch  = @(s,c) struct('string', s, 'count', c) ;
 match     = setMatch('', 0) ;
 hashtable = java.util.Hashtable() ;
 for k = 1 : length(C)
     if isempty(C{k}), continue ;  end
     if hashtable.containsKey(C{k})
         count = hashtable.get(C{k}) ;
         if count >= match.count,  match = setMatch(C{k}, count+1) ;  end
         hashtable.put(C{k}, count+1) ; 
     else
         if match.count == 0,  match = setMatch(C{k}, 1) ;  end
         hashtable.put(C{k}, 1) ; 
     end
 end

Running this leads to;

 >> match
 match = 
    string: 'rj'
     count: 3

5 Comments

Cedric Wannaz on 26 Apr 2013

If C is a "2D" cell array, yo can get column e.g. 4 as follows:

 C_col = C(:,4) ;

The simplest way to apply either solution (The Cyclist or mine) to all columns is to loop over columns of your cell array, and to save the result in another cell array e.g.

 matches = cell(1, size(C, 2)) ;
 for c = 1 : size(C, 2)
    C_col = C(:,c) ;
    % .. whichever method, applied to C_col ..
    matches{c} = .. the solution, e.g. match.string
 end
effess on 26 Apr 2013

i did it but i'm geting an error when trying to save results from columns with more than one string!!

for k=1:length(tsf)
cellData = labelw(:,tsf(k));
indexToEmpty = cellfun(@isempty,cellData);
cellData(indexToEmpty) = [];
[uniqueCellData(:,k),~,whichCell] = unique(cellData);
end; 
Cedric Wannaz on 26 Apr 2013

You don't need to save the content of temporary variables at each iteration of the loop. You just need to save results, and you should have something like (where the ".." have to be adapted to your case):

 maxCountElements = cell(size(..), 1) ;
 for k = 1 : ..
    cellData = ..
    indexToEmpty = cellfun(@isempty,cellData);
    cellData(indexToEmpty) = [];
    uniqueCellData = unique(cellData);
    [uniqueCellData,~,whichCell] = unique(cellData);
    cellCount = hist(whichCell,unique(whichCell));
    [~,indexToMaxCellCount] = max(cellCount);
    maxCountElements{k} = uniqueCellData(indexToMaxCellCount) ;
 end
Cedric Wannaz
Answer by the cyclist on 26 Apr 2013
Edited by the cyclist on 26 Apr 2013

Quite convoluted, but I think this works:

cellData = {[];[];[];[];[];[];[];[];'rj';'rj';'rj';'rj';'rj';'rj';'rj';'rj';'rj';'rj';'rj';'rj';'rj';'rj';}
indexToEmpty = cellfun(@isempty,cellData);
cellData(indexToEmpty) = {''};
uniqueCellData = unique(cellData);
[~,whichCell] = ismember(cellData,unique(uniqueCellData))
cellCount = hist(whichCell,unique(whichCell));
[~,indexToMaxCellCount] = max(cellCount);
maxCountElement = uniqueCellData(indexToMaxCellCount)

The essence of the algorithm is using the hist() function to count up the frequency. Unfortunately, that function only works on numeric arrays, so I had to use the ismember() command to map the cell array values to numeric values.

A further complication was the existence of the empty cell elements. I replaced them with empty strings. You'll need to be careful if your original array has empty strings.

3 Comments

effess on 26 Apr 2013

maybe i did ask the question wrong, but if i have more {''} it will give me that name. instead i want {'rj'}. is there a workaround to counting?

Matt J on 26 Apr 2013

No need for ismember,

[uniqueCellData,~,whichCell] = unique(cellData);
the cyclist on 26 Apr 2013

I knew I had overlooked something easier. :-)

the cyclist

Contact us