# how can I group pairs of numbers that share a common number? Thank you!

8 views (last 30 days)
Jonathan Salazar on 24 Aug 2017
Commented: Steven Lord on 23 Mar 2022
I have pairs of numbers that represent stacked platelets, I want to continue stacking these platelets by realizing that if i have pairs 1,2;2,4;5,7;1,3;7,8;10,9 that 1 2 4 3 are in the same stack and that 5 7 8 are in the same stack and 9 and 10 are in the same stack then I need to count how many of each stack size there is. Thank you!

Steven Lord on 24 Aug 2017
You could treat this as a graph theory problem. Use A as the list of source and destination nodes, construct a graph from it, and use the conncomp function on the graph to identify which nodes are in the same group / component.
Steven Lord on 23 Mar 2022
Or:
A = [1,2; 2,4; 5,7; 1,3; 7,8; 10,9];
G = graph(A(:,1), A(:,2));
components = conncomp(G, 'OutputForm', 'cell')
components = 1×4 cell array
{[1 2 3 4]} {[5 7 8]} {} {[9 10]}

Jan on 24 Aug 2017
Edited: Jan on 24 Aug 2017
Version 1: Create the stacks as cells and search in them iteratively:
P = [1,2; 2,4; 5,7; 1,3; 7,8; 10,9];
nP = size(P, 1);
S = cell(1, nP); % Pre-allocate list of stacks
cS = 0; % Number of stacks
for iP = 1:nP % Loop over pairs
aP = P(iP, :); % Current pair
found = false; % Check is any element exists in a stack already
for iS = 1:cS
if any(aP(1) == S{iS}) || any(aP(2) == S{iS})
% Or: if any(ismember(aP, S{iS}))
S{iS} = unique([S{iS}, aP]); % Insert both elements
found = true;
break;
end
end
if ~found % Create a new stack, if no matching was found
cS = cS + 1;
S{cS} = aP;
end
end
S = S(1:cS); % Crop unused cells

Jan on 24 Aug 2017
Edited: Jan on 24 Aug 2017
Alternative:
P = [1,2; 2,4; 5,7; 1,3; 7,8; 10,9];
nP = size(P, 1); % Number of pairs
iS = 0; % Current stack counter
G = zeros(nP, 1); % Group
for iP = 1:nP % Loop over pairs
aP = P(iP, :); % Current pair
[k, ~] = find(P(1:iP-1, :) == aP(1), 1); % 1st element occurred before?
if isempty(k) % No
[k, ~] = find(P(1:iP-1, :) == aP(2), 1); % 2nd element occurred before?
if isempty(k) % No
iS = iS + 1; % Then it is a new stack
G(iP) = iS; % Set group to new stack index
else
G(iP) = G(k); % 2nd lement found, use former group number
end
else
G(iP) = G(k); % 1st element found, use former group number
end
end
% Create cell containing the stacks:
S = splitapply(@(x) {unique(x(:))}, P, G);
% Perhaps faster but uglier:
% S = accumarray(G, (1:nP).', [], @(k) {unique(reshape(P(k, :), 1, []))})

John BG on 24 Aug 2017
Hi Jonathan
this is John BG jgb2012@sky.com
1.
w is going to log the pairs, here simulated with randi
w=[0 0];
2.
the patterns to search
L1=[1 2 4 3]; % patterns to search, without order
L2=[5 7 8];
L3=[9 10];
3.
logic conditions, one for each pattern
cond1=0;cond2=0;cond3=0;
4.
keep generating with randi until all 3 conditions met
while ~(cond1 && cond2 && cond3)
w=[w;randi([1 10],10,2)];
if numel(intersect(w(:,1),L1))==numel(L1) || numel(intersect(w(:,2),L1))==numel(L1)
cond1=1;
else
cond1=0;
end
if numel(intersect(w(:,1),L2))==numel(L2) || numel(intersect(w(:,2),L2))==numel(L2)
cond2=1;
else
cond2=0;
end
if numel(intersect(w(:,1),L3))==numel(L3) || numel(intersect(w(:,2),L3))==numel(L3)
cond3=1;
else
cond3=0;
end
end
w(1,:)=[]
.
the randomly generated stack stops growing when all 3 conditions met
w =
5 9
7 8
3 9
8 1
9 7
1 9
8 3
7 3
9 6
3 9
8 4
2 3
9 2
7 1
1 2
10 9
6 4
6 8
4 10
8 6
.
5.
checking conditions met
cond1
cond2
cond3
cond1 =
1
cond2 =
1
cond3 =
1
6.
the length of the stack right when all 3 conditions have 1st been met is
L_stack=size(w,1)
L_stack =
20
since your stack may be a measurement, instead of random generation, read from your stack line by line applying same conditions until all 3 met, that to stop reading it's same
~(cond1 && cond2 && cond3)
.
John BG