MATLAB: Find columns with same values in matrix

find column in matrixMATLABrow indices

Hi,
I actually struggle on a fast and good solution on finding columns in an 2D matrix containing same values and returning the row index of those columns.
% Example:
A = [2,2,7,3; ...
8,7,8,10; ...
4,3,5,2; ...
6,7,1,9];
Result should be 2 and 4 because in column 2 the number 7 occurs two times. Is there anything similar to unique or anything else? I try to avoid looping every column with unique since there will be a lot of matrices and bigger ones.
Thanks a lot!

Best Answer

I changed your example matrix to include a variety of duplicates.
% Example:

A = [2,2,7,3,5,0;8,7,8,10,5,0;4,3,5,3,9,0;6,7,1,9,9,1];
A =
2 2 7 3 5 0
8 7 8 10 5 0
4 3 5 3 9 0
6 7 1 9 9 1
As you can see, columns 2, 4, 5 & 6 have duplicates and column 5 has 2 sets while column 6 has three of the same value.
% identify the duplicate values
dupIdx = splitapply(@(x){histc(x,unique(x))>1}, A, 1:size(A,2));
unqVals = splitapply(@(x){unique(x)}, A, 1:size(A,2));
dupVals = cellfun(@(x,y)x(y), unqVals, dupIdx, 'UniformOutput', false);
% List the rows that contain duplicate values for each column

dupRows = splitapply(@(x,y) {find(ismember(x,[y{:}]))}, A, dupVals, 1:size(A,2));
% List the column numbers that contain duplicates

hasDup = find(~cellfun(@isempty, dupRows));
So, dupRows{2} will list the row numbers of column 2 that contain a duplicate. It's empty if col 2 has no duplicates.
hasDup is a vector of column numbers that contain a duplicate. It's empty if there are no duplicates in any column.
[UPDATE] For matlab releases before 2015b, here's the same method using cellfun() instead of splitapply()
% Example:
A = [2,2,7,3,5,0;8,7,8,10,5,0;4,3,5,3,9,0;6,7,1,9,9,1];
Acell = mat2cell(A,size(A,1),ones(1,size(A,2)));
dupIdx = cellfun(@(x){histc(x,unique(x))>1}, Acell);
unqVals = cellfun(@(x){unique(x)}, Acell);
dupVals = cellfun(@(x,y)x(y), unqVals, dupIdx, 'UniformOutput', false);
% List the rows that contain duplicate values for each column
dupRows = cellfun(@(x,y) find(ismember(x,y(:))), Acell, dupVals,'UniformOutput', false);
% List the column numbers that contain duplicates
hasDup = find(~cellfun(@isempty, dupRows));
% Alternative
% hasDup = any(([ones(1,size(A,2));diff(sort(A))]~=0)==0);