Element extraction from Matrix based on column index from another matrix.

2 views (last 30 days)
Good afternoon/good day Matlab community, I would like some help with an exercise that I am trying to complete giving two input matrices, A and B. Suppose A is(3*3) and B is (3*9). The first two columns in both matrices have unique ID's to each row A(:,3) and B(:,9) The output matrix C is C(3*3) with C(:,1) and C(:,2) are exactly the same as A(:,1) and A(:,2), and C(:,3) should be extracted from matrix B using A(:,1) unique identifier to match B(:,1) unique IDs while indexing the column position using A(:,2)+1. Please see the m.code with the example attached, (to make it clear, A is a matrix not a cell array, but I had to build it into a cell array to differentiate the column names where the first column has unique identifier info for each row) Thank you so much.
%%A is the first matrix, first column has unique identifier for each row....
%%%B is the second input matrix (3*9) and the first column has unique
%%%identifiers for each row.
%%%C is the desired output matrix: with the first column containing the
%%%same unique identifiers as matrix A, second column has the same info
%%%from Matrix A as well, and the 3rd column elements are basically
%%%extracted from B based on column indexing using A(:,2).
%%%Example here
A={'UniqueID', 19 17 15 ;'ColumnIndex', 3 5 7 ;'Carbonvalue', 5 3 9}'
B=[ 15 2 3 5 8 9 7 4 5 ;19 2 2.5 3 3.5 4 4.5 5 5.5 ; 17 1 5 4 3 6 8 7 4 ];
C=[19,3, 3; 17,5,6; 15,7,4];
%%so for example C(1,1)=A(1,1)
%%%C(1,2)=A(1,2)
%%%%C(1,3)=The element from B with the same row unique
%%%%identifier as A, but at column index A(1,2)+1
%%%The reason I indexed it using +1 because the elements of first column
%%%of B all unique idnetifiers, so B data starts from column
%%%2 through column 9.
%%%%%%%

Accepted Answer

Guillaume
Guillaume on 19 Dec 2016
The fact that A is a cell array makes things a bit awkward, but otherwise it's trivial to do with ismember to find the matching rows, and sub2ind to index B from the row and column indices:
Avalues = cell2mat(A(2:end, :)); %to make things easier
[isinB, Brow] = ismember(Avalues(:, 1), B(:, 1));
assert(all(isinB), 'Some ID in A are not in B');
C = [Avalues(:, [1 2]), B(sub2ind(size(B), Brow, Avalues(:, 2) + 1))]
  4 Comments
Guillaume
Guillaume on 19 Dec 2016
See assert documentation. In this case, it checks that all the A ids are indeed in B and throws an error otherwise (with the message 'Some ID in A are not in B'.
Without the assert, if some IDs in A are not in B, you'll get an error in the next line with the error message 'Error using sub2ind, Out of range subscript', which is arguably a lot more obscure (and is due to the fact you'd be trying to index B with a 0 index returned by ismember).
It's always a good to check your assumptions with assert and a clear error message. Otherwise, you will, one day, forget that you assumed that all A ids were in B and spend time wondering why you get an obscure error.
Alternatively, modify the code so that it can cope with missing IDs:
Avalues = cell2mat(A(2:end, :)); %to make things easier
[isinB, Brow] = ismember(Avalues(:, 1), B(:, 1));
C = [Avalues(isinB, [1 2]), B(sub2ind(size(B), Brow(isinB), Avalues(isinB, 2) + 1))]
which only returns those rows of A that matched.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!