How to get all the rows of the table (or dataset) of object A that correspond to some row of the table (or dataset) of object B?

Let Aand Bbe two objects table(or dataset) having several factor variables K1, K2, ..., Kn. I will call these n factors key factors . In addition, I will say that the string Aand the string B match if they match for these key factors, i.e. iff A.K1 == B.K1 & A.K2 == B.K2 & ... & A.Kn == B.Kn.

(I will give an example above, with the code at the end of this post.)

I am looking for an efficient way to retrieve all rows Athat "match" one row 1B .

(More precisely, I want to generate a new table Cconsisting of all rows Athat "match" one row B.)


Is there an effective way to do this? (I'm trying to avoid for-Loop Hell here or any solution that depends on knowing, say, the number of key factors, etc., since I want to use this in code that knows little about Aand Buntil runtime.)

I tried intersect(A, B), but the error fails:

>> keyfactors = intersect(A.Properties.VarNames, B.Properties.VarNames);
>> intersect(A, B, keyfactors)
Error using table/intersect (line 41)
A and B must contain the same variables.

The only other strategy that I can come up with (although I still don't know how to implement it) is to somehow synthesize the function on the fly based on the information encoded in B. For example, given an index table Bsuch as

B = cell2table({
                'even', 'red', 'diamonds';
                'odd', 'yellow', 'spades';
                'odd', 'green', 'hearts'
               }, 'VariableNames', ...
               {'Parity', 'TrafficLight', 'Suit'});

... - ​​,

fn = @(c) any([all([strcmp(c(:, 1), 'even'), ...
                    strcmp(c(:, 2), 'red'), ...
                    strcmp(c(:, 3), 'diamonds')], 2), ...
               all([strcmp(c(:, 1), 'odd'), ...
                    strcmp(c(:, 2), 'yellow'), ...
                    strcmp(c(:, 3), 'spades')], 2), ...
               all([strcmp(c(:, 1), 'odd'), ...
                    strcmp(c(:, 2), 'green'), ...
                    strcmp(c(:, 3), 'hearts')], 2)], 2);

..., :

Ac = table2cell(A);
C = cell2table(Ac(fn(Ac), :), ...
               'VariableNames', B.Properties.VariableNames);

, , ​​, fn , ( ) eval.


A B, . ( , MATLAB, ( ) table, , "table" "VariableNames" " " "VarNames" ", .)

% "data" table
A = cell2table({
                'even', 'red', 'spades', 38, 0.9837;
                'even', 'red', 'hearts', 19, 0.5695;
                'even', 'red', 'diamonds', 89, 0.2629;
                'even', 'red', 'diamonds', 98, 0.3578;
                'even', 'red', 'diamonds', 92, 0.2596;
                'even', 'red', 'diamonds', 69, 0.5751;
                'even', 'red', 'diamonds', 77, 0.6318;
                'even', 'yellow', 'clubs', 22, 0.6917;
                'even', 'green', 'spades', 35, 0.6674;
                'even', 'green', 'hearts', 67, 0.7896;
                'even', 'green', 'hearts', 49, 0.5025;
                'even', 'green', 'hearts', 64, 0.5318;
                'odd', 'red', 'spades', 22, 0.5587;
                'odd', 'red', 'hearts', 51, 0.9122;
                'odd', 'red', 'diamonds', 74, 0.3343;
                'odd', 'red', 'diamonds', 69, 0.2911;
                'odd', 'yellow', 'spades', 33, 0.2653;
                'odd', 'yellow', 'spades', 38, 0.2549;
                'odd', 'yellow', 'diamonds', 1, 0.2064;
                'odd', 'yellow', 'diamonds', 25, 0.8257;
                'odd', 'green', 'spades', 64, 0.4348;
                'odd', 'green', 'hearts', 59, 0.8644;
                'odd', 'green', 'hearts', 4, 0.6374;
                'odd', 'green', 'hearts', 11, 0.3354
               }, 'VariableNames', ...
               {'Parity', 'TrafficLight', 'Suit', 'order', 'prevalence'});

% "indexing" table
B = cell2table({
                'i', 'even', 'red', 'diamonds';
                'ii', 'odd', 'yellow', 'spades';
                'iii', 'odd', 'green', 'hearts'
               }, 'VariableNames', ...
               [{'class'} A.Properties.VariableNames(1:3)]);

keyfactors = intersect(B.Properties.VariableNames, ...
                       A.Properties.VariableNames, ...
                       'stable');

% this fails:
% intersect(A, B, keyfactors);

% desired subtable would look like this one
C = cell2table({
                'even', 'red', 'diamonds', 89, 0.2629;
                'even', 'red', 'diamonds', 98, 0.3578;
                'even', 'red', 'diamonds', 92, 0.2596;
                'even', 'red', 'diamonds', 69, 0.5751;
                'even', 'red', 'diamonds', 77, 0.6318;
                'odd', 'yellow', 'spades', 33, 0.2653;
                'odd', 'yellow', 'spades', 38, 0.2549;
                'odd', 'green', 'hearts', 59, 0.8644;
                'odd', 'green', 'hearts', 4, 0.6374;
                'odd', 'green', 'hearts', 11, 0.3354
               }, 'VariableNames', ...
               {'Parity', 'TrafficLight', 'Suit', 'order', 'prevalence'});

1 , B ( "" ) . true A. A , B "" (.. ) , A. B " " A.

+3
1

, , , , :

[~,iB,iA] = intersect(B.Properties.VariableNames, ...
                      A.Properties.VariableNames, ...
                      'stable');
C = A(ismember(A(:,iA),intersect(A(:,iA),B(:,iB),'stable')),:)

, table/intersect . table/ismember , .

+3

All Articles