# Grouping values in a matrix according to a value in a row & its index position

6 views (last 30 days)
JIAN-HONG YE ZHU on 16 Mar 2023
Commented: Dyuman Joshi on 19 Mar 2023
Hello, say I have the following matrix:
51 71 0
48.87 63.38 -2.30769230769231
42.15 55.97 -2.30769230769231
40.22 47.47 -2.30769230769231
39.84 38.75 -1.92307692307692
40.577 34.19 -1.15384615384615
50 30 0
And I wanted to group different rows together according to equal values of the 3rd column, but index position matters, so if I have two equal values in a 3rd column but they are not next to each other in their index position, do not group together.
Which would give me:
51 71 0
48.87 63.38 -2.30769230769231
42.15 55.97 -2.30769230769231
40.22 47.47 -2.30769230769231
39.84 38.75 -1.92307692307692
40.577 34.19 -1.15384615384615
50 30 0
Would I be using the unique function? Thanks
##### 2 CommentsShow 1 older commentHide 1 older comment
JIAN-HONG YE ZHU on 16 Mar 2023
Fixed

Dyuman Joshi on 16 Mar 2023
Edited: Dyuman Joshi on 16 Mar 2023
Vectorized approach
mat=[51 71 0
48.87 63.38 -2.30769230769231
42.15 55.97 -2.30769230769231
40.22 47.47 -2.30769230769231
39.84 38.75 -1.92307692307692
40.577 34.19 -1.15384615384615
50 30 0];
vec=(1:size(mat,1))';
%Indices of rows in 3rd column which are not equal to the next row
%Using tolerance instead of comparing to zero
idx=vec([abs(diff(mat(:,3)))>1e-4;true])
idx = 5×1
1 4 5 6 7
%Corresponding number of rows in each group
elem=diff([0;idx])
elem = 5×1
1 3 1 1 1
%Output
out=mat2cell(mat,elem)
out = 5×1 cell array
{[ 51 71 0]} {3×3 double } {[39.8400 38.7500 -1.9231]} {[40.5770 34.1900 -1.1538]} {[ 50 30 0]}
"what if I wanted each group to be stored in a different matrix and each value is in its corresponding column"
Any particular reason why you want to do that?
You can do that, but it is not recommended, as it inefficient and difficult to work with. Read - Why Variables should not be named Dynamically
##### 2 CommentsShow 1 older commentHide 1 older comment
Dyuman Joshi on 19 Mar 2023
You can do that from via the cell array as well.
mat=[51 71 0
48.87 63.38 -2.30769230769231
42.15 55.97 -2.30769230769231
40.22 47.47 -2.30769230769231
39.84 38.75 -1.92307692307692
40.577 34.19 -1.15384615384615
50 30 0];
vec=(1:size(mat,1))';
idx=vec([abs(diff(mat(:,3)))>1e-4;true]);
elem=diff([0;idx]);
%storing only 1st 2 columns
out=mat2cell(mat(:,1:2),elem);
out{2}(1,:)
ans = 1×2
48.8700 63.3800
out{3}
ans = 1×2
39.8400 38.7500
norm(out{2}(1,:)-out{3})
ans = 26.2331

Amit Dhakite on 16 Mar 2023
Edited: Amit Dhakite on 16 Mar 2023
Hi Jian-Hong,
As per my understanding, you want to group different rows based on the equal values of the 3rd column, only if these rows are next to each other.
The unique() function can indeed be used to group rows based on equal values in a specific column. However, it does not take into account the index position of the rows, and therefore it would not meet your requirement of only grouping together rows with equal values in the 3rd column if they are next to each other in their index position.
To achieve this, you can manually loop through the matrix and group the rows. The approach is to initialize an empty cell array to store the groups of rows. Then, you loop through the sorted matrix and group the rows with equal 3rd column values together. Finally, you display the groups of rows. It can be done as follows:
% Example matrix
A = [51 71 0; 48.87 63.38 -2.30769230769231; 42.15 55.97 -2.30769230769231; 40.22 47.47 -2.30769230769231; 39.84 38.75 -1.92307692307692; 40.577 34.19 -1.15384615384615; 50 30 0];
% Initialize cell array for storing groups of rows
groups = {};
% Loop through sorted matrix and group rows with equal 3rd column values together
currentGroup = [];
currentValue = A(1,3);
for i = 1:size(A,1)
if A(i,3) == currentValue
currentGroup = [currentGroup; A(i,:)];
else
groups = [groups; {currentGroup}];
currentGroup = A(i,:);
currentValue = A(i,3);
end
% if its the last row, then just add this currentGroup to the groups
% array
if i == size(A,1)
groups = [groups; {currentGroup}];
end
end
% Display the groups of rows
for i = 1:numel(groups)
disp(['Group ', num2str(i), ':']);
disp(groups{i});
end
Group 1:
51 71 0
Group 2:
48.8700 63.3800 -2.3077 42.1500 55.9700 -2.3077 40.2200 47.4700 -2.3077
Group 3:
39.8400 38.7500 -1.9231
Group 4:
40.5770 34.1900 -1.1538
Group 5:
50 30 0
To know more about the functions used above, kindly refer to the following links:
JIAN-HONG YE ZHU on 16 Mar 2023
Hello, thanks a lot for your explanation. I see the the groups are stored in a 5x1 cell, what if I wanted each group to be stored in a different matrix and each value is in its corresponding column?

### Categories

Find more on Creating and Concatenating Matrices in Help Center and File Exchange

R2022b

### Community Treasure Hunt

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

Start Hunting!