## Follow up: How can I merge two different tables using the first column in common?

### elmar.a (view profile)

on 21 May 2019
Latest activity Commented on by Jos (10584)

on 22 May 2019

### Jos (10584) (view profile)

This question is related to How can I merge two different tables using the first column in common? but the accepted answer does not fully solve my issue.
I have a case where there are more than two arrays, some of which have the same identifier in the first column, such as
A = [1 7;
3 15]
B = [2 9;
5 10]
C = [2 5;
3 4]
From this I'd like to get
[1 7 0 0;
2 0 9 5;
3 15 0 4;
4 0 0 0;
5 0 10 0]
that means if identifiers are the same (as for row 3) the values of A, B, and C should appear in the same row.

on 21 May 2019
Not clear, more explanation needed.

on 21 May 2019
Column 1 is just a row index number.
Column 2 are the number is col 2 of "A". Column 3 are the numbers in col 2 of "B". Column 4 are the numbers in col 2 of "C".

### Jos (10584) (view profile)

on 21 May 2019

% data, (showing the drawback of storing relates things in different variables)
A = [1 7;
3 15]
B = [2 9;
5 10]
C = [2 5;
3 4]
% simple indexing engine
A(:,3) = 2, B(:,3) = 3, C(:,3) = 4 % add column numbers to input
D = cat(1,A,B,C)
sz = [max(D(:,1)), D(end,3)]
m = zeros(sz)
m(D(:,1), 1) = D(:,1)
m(sub2ind(sz, D(:,1), D(:,3))) = D(:,2)

elmar.a

### elmar.a (view profile)

on 22 May 2019
Thanks, that does the job. I like this short solution!

on 21 May 2019

on 21 May 2019

I find it easier to first combine the matrices into a 3D array. This should work with any number of matrices as long as they are the same size. "m" is your final matrix.
ABC = cat(3,A,B,C);
% Create final matrix (all 0s except first column)
m = zeros(max(ABC(:,1,:),[],'all'),size(ABC,3)+1); %prior to r2018b: zeros(max(max(squeeze(ABC(:,1,:)))),size(ABC,3)+1)
m(:,1) = 1:size(m,1);
% Find the column and row indices of M for the elements in ABC
colID = reshape(repelem(2:size(ABC,3)+1,size(ABC,2),size(ABC,2)-1,1),[],1);
[~, rowID] = ismember(reshape(ABC(:,1,:),[],1),m(:,1));
% fill in the rest of the m matrix
m(sub2ind(size(m),rowID,colID)) = ABC(:,2:end,:);
Result
m =
1 7 0 0
2 0 9 5
3 15 0 4
4 0 0 0
5 0 10 0

Jos (10584)

### Jos (10584) (view profile)

on 22 May 2019
Note that this solution assumes that all matrices have the same size.

on 22 May 2019
Yeah, I mentioned that in the answer (2nd sentence).
Jos' answer is more fleixible because it allows for varying number of rows.
Jos (10584)

on 22 May 2019

### Guillaume (view profile)

on 21 May 2019

The question is a bit confusing. Tables are mentioned in the title, but the examples are matrices. Two tables is mentioned in the table, but the example has 3 inputs.
If you were dealing with tables, you'd use outerjoin for what you want:
A = [1 7;
3 15]
B = [2 9;
5 10]
C = [2 5;
3 4]
%cell array of tables
t{1} = array2table(A, 'VariableNames', {'ID', 'A'});
t{2} = array2table(B, 'VariableNames', {'ID', 'B'});
t{3} = array2table(C, 'VariableNames', {'ID', 'C'});
result = outerjoin(t{1}, t{2}, 'MergeKeys', true); %outer join the first two
for tidx = 3:numel(t) %loop over the rest (works with any number of tables)
result = outerjoin(result, t{tidx}, 'MergeKeys', true);
end