How to remove duplicate x-values and rearrange the y-values?

6 views (last 30 days)
Dear Matlab users,
I would like to resolve with your help the following problem. I have multiple columns filled with x and y values in repeating order such as:
Col(1): x1 x1 x1 x2 x2 x3 x4 x4
Col(2): y1 y2 y3 y4 y5 y6 y7 y8
Col(n-1): x1 x1 x2 x3 x3
Col(n): y1 y2 y3 y4 y5
How would it be possible to rearrange the data into a form where the Col(1) would contain x-values without duplicates with corresponding y-values in the remaining columns? Something like:
Col(1): x1 x2 x3 x4
Col(2): y1 y4 y6 y7
Col(3): y2 y5 y4 y8
Col(4): y3 y3 y5
Col(5): y1
Col(6): y2
Your help is greatly appreciated. Thank you.

Accepted Answer

Marián Matejdes
Marián Matejdes on 16 May 2022
Edited: Marián Matejdes on 16 May 2022
% raw_data matrix containing x, y, x, y, ... columns
new_data(:,1) = raw_data(:,1:2:end);
new_data(:,2) = raw_data(:,2:2:end);
% removing NaN values and sorting in ascending order
sort_data = sortrows(rmmissing(new_data));
% removing x-value duplicates, reduced matrix, unique with a small
% tolerance (it needs to be included)
[a,index] = uniquetol(sort_data(:,1));
% saving unique values into first column of uniqueMat
uniqueMat(:,1) = a;
% adding an extra row to index
index(length(index)+1) = length(sort_data)+1;
% filling the uniqueMat matrix with 0 and y-values
for i = 1:length(uniqueMat)
uniqueMat(i,(index(i)+1):index(i+1)) = sort_data(index(i):index(i+1)-1,2);
[R,S] = size(uniqueMat);
% picking up only the 2:S columns due to the possible 0 in the first column
X = uniqueMat(:,2:S);
% all elements of X equal to 0 will be converted to NaN
X(X == 0) = NaN;
% first column of uniqueMat filled with unique x-values
uniqueMat(:,1) = a;
% all other columns filled with y-values and NaN
uniqueMat(:,2:S) = X;
% creating final_data matrix filled with NaN
final_data = NaN(R,S);
% counting cells of uniqueMat which doesn't contain NaN with logical isnan
for i = 1:R
num_val(i,1) = S-sum(isnan(uniqueMat(i,:)));
final_data(i,1:num_val(i)) = rmmissing(uniqueMat(i,:));
% cropping the final_data matrix
final_data = final_data(:,1:max(num_val));

More Answers (2)

Walter Roberson
Walter Roberson on 9 May 2022
g = findgroups(x)
Col = splitapply(@(Y) {Y}, y, g) ;

Jonas on 9 May 2022
Edited: Jonas on 9 May 2022
yourMat=[ [4; 1; 1; 2; 3; 3; 5; 10 ], rand(8,4)];
[~,index]=unique(yourMat(:,1),'stable'); % get unique values from the first column of your matrix/cell without sorting the values
diminishedMat = 6×5
4.0000 0.3450 0.5707 0.1908 0.5958 1.0000 0.8221 0.2884 0.4012 0.7886 2.0000 0.4300 0.0018 0.0691 0.2521 3.0000 0.5942 0.9363 0.3777 0.3080 5.0000 0.8913 0.4600 0.3938 0.3140 10.0000 0.7392 0.3923 0.4889 0.0321
  1 Comment
Marián Matejdes
Marián Matejdes on 9 May 2022
thank you for your answer, the problem is that the information represented by y-values is reduced. yourMat contains 8x4 y-values, while diminishedMat only 6x4. The information wouldn't be reduced if row(2) and row(4) of diminishedMat would contain 9 elements including the one x-value.

Sign in to comment.




Community Treasure Hunt

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

Start Hunting!

Translated by