Find the closest value in each group in a matrix column

1 Ansicht (letzte 30 Tage)
Ted Hein
Ted Hein am 18 Mär. 2019
Kommentiert: Ted Hein am 18 Mär. 2019
I have a matrix as below.
a = [1.05 2.1 3.4 1; 1.06 2.2 3.6 1; 2.04 2.3 3.8 2; 2.15 2.2 4.0 2; 1.37 2.3 3.7 1;3.12 2.1 4.1 3;3.02 2.2 4.2 3;3.42 2.3 4.5 3;3.24 2.4 4.8 3]
a =
1.0500 2.1000 3.4000 1.0000
1.0600 2.2000 3.6000 1.0000
2.0400 2.3000 3.8000 2.0000
2.1500 2.2000 4.0000 2.0000
1.3700 2.3000 3.7000 1.0000
3.1200 2.1000 4.1000 3.0000
3.0200 2.2000 4.2000 3.0000
3.4200 2.3000 4.5000 3.0000
3.2400 2.4000 4.8000 3.0000
a(:,4) is group numbers. Based on group numbers, I split the matrix data into 3 groups: 1, 2 and 3.
I would like to find the index of value closest to 2.2 in a(:,2) in each group.
From the data you can see, there is a
2.2 in row 2 belong to group 1,
2.2 in row 4 belong to group 2,
2.2 in row 7 belong to group 3.
My code is shown as below:
[minValue,closestIndex] = splitapply(@(x)min(abs(2.2-x)), a(:,2), findgroups(a(:,4)))
The outcome is:
minValue =
0
0
0
The minimum values are consistent with what we expect, since there are three 2.2 totally.
closestIndex =
2
2
2
This is supposed to be the indexes of three 2.2 in the matrix, which should be 2, 4 and 7. But the outcome is 2, 2 and 2.
What is wrong with my code?

Akzeptierte Antwort

Guillaume
Guillaume am 18 Mär. 2019
Within splitapply, when min is invoked, it's invoked on a single group. Therefore, the index it returns refers to the index of the minimum within the group. It looks like it's the 2nd element of each group which is the minimum.
Using just one splitapply call, you won't be able to achieve what you want with an anonymous function, you'll need an explicit function:
function globalindex = locmingroup(values, indices)
[~, where] = min(abs(values - 2.2));
globalindex = indices(where);
end
Your splitapply call then becomes:
closestIndex = splitapply(@locmingroup, a(:, 2), (1:size(a, 1))', findgroups(a(:, 4)));
Note that if a(:, 4) is integers from 1 with no gap, as in your example, you don't need findgroups, you can just pass a(:, 4) directly.

Weitere Antworten (0)

Kategorien

Mehr zu Get Started with MATLAB finden Sie in Help Center und File Exchange

Tags

Produkte


Version

R2018a

Community Treasure Hunt

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

Start Hunting!

Translated by