How do I find the mode of an array and verify it using the frequency?

35 views (last 30 days)
A very basic question, but I am just getting back into it and I'm struggling to find the right answer on the forums (or I very bad at using Google?).
I have an array which is 100x50 and want to find the mode of each row. When I run the below function, it provides a 98% correct solution. Two of the rows have a mix of values and it is not as easy to tell the mode, whereas the other 98 rows have a distint value. Is it possible to set a threshold so that out of the row, if the value is only less than 30% of the total value then ignore it?
So if row 99 has a value of 1 as the mode, but 1 only occurs 20% (10/50) of the time in the total row then ignore it.
mode(a(:,:));

Answers (2)

Walter Roberson
Walter Roberson on 25 Aug 2025 at 11:10
By definition, mode() returns a value such that no other value is more frequent (but other values might be equally frequent.)
If a potential candidate for the mode is not one of the values that is the most frequent, then that candidate will not be selected.
Now consider the possibilities: if "1" is the selected mode() for a row, then every other value in the row is either less frequent or the same frequency as "1". If "1" occurs only 20% of the time and if no other value occurs with equal frequency... then every other value must also be less than 20% of the values. If "1" occurs only 20% of the time and some other value occurs with the same frequency, then those other values must also occur less than 20% of the values.
Thus, your condition of ignoring the candidate mode if it occurs less than some percentage of the time, is equivalent to saying that for that particular row, the returned mode value must be either empty or NaN, since every other value on the row must occur with frequency no greater than the given percentage, However, mode() of an array row-wise cannot return empty in any row slot, so mode() of the array would have to return NaN for that row.
Is that what you want? That you get back NaN for rows with low frequency ??
  1 Comment
Walter Roberson
Walter Roberson on 25 Aug 2025 at 11:14
If so, then use the syntax
[M,F] = mode(___)
The F array will return the frequency count for each selected M.
cutoff = 20/100;
[M, F] = mode(A, 2);
M(F < size(A,2)*cutoff) = NaN;

Sign in to comment.


Umar
Umar on 25 Aug 2025 at 14:54
Edited: Torsten on 25 Aug 2025 at 17:19
Hi @ Caleb Crawdad,
I reviewed your question regarding row-wise mode computation and the 30% dominance threshold. As you noticed, MATLAB’s built-in `mode` function returns the most frequent value but does not consider whether that value is statistically dominant in the row.
Inspired by Walter Roberson’s vectorized approach on MATLAB Answers, I implemented a _row-wise solution_ that is fully transparent and easy to follow.
*This script:*
* Computes the **row-wise mode** explicitly for each row.
* Calculates the **relative frequency** of the mode.
* Applies a **30% threshold**, marking rows with ambiguous modes as `NaN`.
* Handles **tie-breaks deterministically** (chooses the smallest value).
* Provides full transparency for analysis, showing both the candidate mode and its relative frequency.
*Here’s the MATLAB script:*
clear all; clc; close all;
A = randi([1 5],100,50); % Example 100x50 matrix
threshold = 0.3; % minimum fraction for mode
[rowCount, colCount] = size(A);
RowIndex = (1:rowCount)';
CandidateMode = NaN(rowCount,1);
RelFrequency = NaN(rowCount,1);
ModeWithThreshold = NaN(rowCount,1);
for i = 1:rowCount
row = A(i,:);
[uniqueVals, ~, idx] = unique(row);
counts = accumarray(idx,1);
maxCount = max(counts);
posTies = find(counts == maxCount);
modeVal = min(uniqueVals(posTies));
relFreq = maxCount / colCount;
CandidateMode(i) = modeVal;
RelFrequency(i) = relFreq;
if relFreq >= threshold
ModeWithThreshold(i) = modeVal;
else
ModeWithThreshold(i) = NaN;
end
end
ResultTable = table(RowIndex, CandidateMode, RelFrequency, ModeWithThreshold, ...
'VariableNames', {'RowIndex','CandidateMode','RelFrequency','ModeWithThreshold'});
disp(ResultTable);
RowIndex CandidateMode RelFrequency ModeWithThreshold ________ _____________ ____________ _________________ 1 2 0.3 2 2 5 0.3 5 3 4 0.32 4 4 2 0.22 NaN 5 3 0.24 NaN 6 5 0.3 5 7 3 0.24 NaN 8 3 0.3 3 9 1 0.3 1 10 4 0.24 NaN 11 4 0.28 NaN 12 5 0.24 NaN 13 4 0.32 4 14 3 0.24 NaN 15 3 0.34 3 16 2 0.3 2 17 1 0.26 NaN 18 1 0.28 NaN 19 1 0.26 NaN 20 1 0.24 NaN 21 3 0.26 NaN 22 5 0.24 NaN 23 4 0.28 NaN 24 4 0.24 NaN 25 5 0.26 NaN 26 5 0.26 NaN 27 5 0.3 5 28 4 0.34 4 29 5 0.36 5 30 4 0.24 NaN 31 2 0.26 NaN 32 5 0.28 NaN 33 3 0.26 NaN 34 3 0.3 3 35 4 0.28 NaN 36 3 0.28 NaN 37 1 0.24 NaN 38 4 0.24 NaN 39 2 0.3 2 40 2 0.3 2 41 3 0.34 3 42 1 0.26 NaN 43 4 0.24 NaN 44 3 0.26 NaN 45 5 0.3 5 46 2 0.26 NaN 47 2 0.3 2 48 4 0.26 NaN 49 3 0.24 NaN 50 5 0.28 NaN 51 5 0.34 5 52 3 0.26 NaN 53 5 0.26 NaN 54 3 0.26 NaN 55 2 0.3 2 56 4 0.32 4 57 3 0.26 NaN 58 3 0.3 3 59 5 0.24 NaN 60 3 0.26 NaN 61 2 0.3 2 62 2 0.26 NaN 63 3 0.24 NaN 64 3 0.3 3 65 4 0.3 4 66 2 0.3 2 67 2 0.26 NaN 68 1 0.28 NaN 69 5 0.28 NaN 70 5 0.24 NaN 71 1 0.24 NaN 72 3 0.24 NaN 73 5 0.26 NaN 74 4 0.28 NaN 75 5 0.28 NaN 76 3 0.24 NaN 77 3 0.3 3 78 2 0.32 2 79 2 0.24 NaN 80 4 0.32 4 81 2 0.22 NaN 82 3 0.3 3 83 1 0.28 NaN 84 1 0.34 1 85 5 0.26 NaN 86 5 0.24 NaN 87 2 0.24 NaN 88 2 0.28 NaN 89 5 0.28 NaN 90 3 0.28 NaN 91 2 0.24 NaN 92 1 0.22 NaN 93 3 0.3 3 94 1 0.24 NaN 95 1 0.28 NaN 96 5 0.32 5 97 4 0.28 NaN 98 1 0.32 1 99 4 0.26 NaN 100 1 0.24 NaN
*Please see attached*
<</matlabcentral/answers/uploaded_files/1839255/IMG_4536.jpeg>>
*How this addresses your concerns:*
1. Row-wise mode:Computed explicitly per row.
2. Threshold enforcement:Modes below 30% are ignored (`NaN`).
3. Ambiguous rows:Easily identifiable with `NaN`.
4. Mixed-value rows:Tie-break handled deterministically.
5. Transparency: `CandidateMode` and `RelFrequency` show exactly how dominant the mode is.
This solution ensures accurate mode detection while clearly filtering non-dominant rows.
  4 Comments
Walter Roberson
Walter Roberson on 25 Aug 2025 at 20:37
My code is much much shorter.
A = randi([1 5],100,50); % Example 100x50 matrix
threshold = 0.3; % minimum fraction for mode
[M, F] = mode(A, 2);
M1 = M;
M1(F < size(A,2)*threshold) = NaN;
table((1:size(M,1)).', M, F./size(A,2), M1)
ans = 100×4 table
Var1 M Var3 M1 ____ _ ____ ___ 1 1 0.34 1 2 5 0.32 5 3 4 0.26 NaN 4 2 0.24 NaN 5 2 0.26 NaN 6 1 0.3 1 7 3 0.28 NaN 8 4 0.3 4 9 1 0.24 NaN 10 4 0.24 NaN 11 3 0.26 NaN 12 2 0.28 NaN 13 4 0.3 4 14 5 0.3 5 15 1 0.34 1 16 5 0.28 NaN
[rowCount, colCount] = size(A);
RowIndex = (1:rowCount)';
CandidateMode = NaN(rowCount,1);
RelFrequency = NaN(rowCount,1);
ModeWithThreshold = NaN(rowCount,1);
for i = 1:rowCount
row = A(i,:);
[uniqueVals, ~, idx] = unique(row);
counts = accumarray(idx,1);
maxCount = max(counts);
posTies = find(counts == maxCount);
modeVal = min(uniqueVals(posTies));
relFreq = maxCount / colCount;
CandidateMode(i) = modeVal;
RelFrequency(i) = relFreq;
if relFreq >= threshold
ModeWithThreshold(i) = modeVal;
else
ModeWithThreshold(i) = NaN;
end
end
ResultTable = table(RowIndex, CandidateMode, RelFrequency, ModeWithThreshold, ...
'VariableNames', {'RowIndex','CandidateMode','RelFrequency','ModeWithThreshold'})
ResultTable = 100×4 table
RowIndex CandidateMode RelFrequency ModeWithThreshold ________ _____________ ____________ _________________ 1 1 0.34 1 2 5 0.32 5 3 4 0.26 NaN 4 2 0.24 NaN 5 2 0.26 NaN 6 1 0.3 1 7 3 0.28 NaN 8 4 0.3 4 9 1 0.24 NaN 10 4 0.24 NaN 11 3 0.26 NaN 12 2 0.28 NaN 13 4 0.3 4 14 5 0.3 5 15 1 0.34 1 16 5 0.28 NaN
Umar
Umar on 28 Aug 2025 at 23:42

Absolutely right, @Walter Robertson! That's a beautifully elegant solution - much more concise and leverages MATLAB's built-in functions perfectly.Your approach using mode(A, 2) directly is brilliant:

  • Gets both the mode values AND frequencies in one function call
  • The threshold filtering with M1(F < size(A,2)*threshold) = NaN is clean and vectorized
  • No loops needed at all!

This is exactly why I appreciate working with experienced MATLAB developers - there's always a more elegant built-in solution than the verbose manual approach. Your code is not just shorter, it's also more readable and computationally efficient.

Thanks for sharing this - definitely learning from your approach here. Sometimes the best solutions are the simplest ones that fully utilize MATLAB's strengths!

Sign in to comment.

Categories

Find more on Matrices and Arrays in Help Center and File Exchange

Products


Release

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!