gusucode.com > datatypes 工具箱matlab源码程序 > datatypes/@tabular/join.m
function [c,ir] = join(a,b,varargin) %JOIN Merge tables or timetables by matching up rows using key variables. % C = JOIN(A, B) creates a table C by merging rows from the two tables A % and B. If both A and B are timetables, C is also a timetable. You can % also merge A and B if A is a timetable and B is a table, but not if A % is a table and B is a timetable. JOIN performs a simple form of join % operation where each row of A must match exactly one row in B. If % necessary, JOIN replicates rows of B and "broadcasts" them out to A. % For more complicated forms of inner and outer joins, see INNERJOIN and % OUTERJOIN. % % JOIN first finds one or more key variables. A key is a variable that % occurs in both A and B with the same name. If both A and B are % timetables, the key variables are the time vectors of A and B. If A is % a timetable and B is a table, the keys are variables that occur in both % A and B with the same name. Each row in B must contain a unique % combination of values in the key variables, and B must contain all % combinations of key values that are present in A's keys. JOIN uses the % key variables to find the row in B that matches each row in A, and % combines those rows to create a row in C. C contains one row for each % row in A, appearing in the same order as rows in A. % % C contains all variables from A, as well as all of the non-key variables % from B. If A and B contain variables with identical names, JOIN adds % a unique suffix to the corresponding variable names in C. Use the % 'KeepOneCopy' input parameter to retain only one copy of variables with % identical names. % % C = JOIN(A, B, 'PARAM1',val1, 'PARAM2',val2, ...) allows you to specify % optional parameter name/value pairs to control how JOIN uses the variables % in A and B. Parameters are: % % 'Keys' - specifies the variables to use as keys. Specify % the character vector 'RowNames' to use A's and % B's rownames as keys. In this case, there must % be a one-to-one correspondence between rows of A % and rows of B. % 'LeftKeys' - specifies the variables to use as keys in A. % 'RightKeys' - specifies the variables to use as keys in B. % % You may provide either the 'Keys' parameter, or both the 'LeftKeys' and % 'RightKeys' parameters. The value for these parameters is a positive % integer, a vector of positive integers, a variable name, a cell array of % variable names, or a logical vector. 'LeftKeys' or 'RightKeys' must both % specify the same number of key variables, and the left and right keys are % paired in the order specified. % % When joining two timetables, 'Keys', or 'LeftKeys' and 'RightKeys', % must be the names of the time vector of the timetables. % % 'LeftVariables' - specifies which variables from A to include in C. % By default, JOIN includes all variables from A. % 'RightVariables' - specifies which variables from B to include in C. % By default, JOIN includes all variables from B except % the key variables. % % 'LeftVariables' or 'RightVariables' can be used to include or exclude key % variables as well as data variables. The value for these parameters is a % positive integer, a vector of positive integers, a variable name, a cell % array containing one or more variable names, or a logical vector. % % 'KeepOneCopy' - When A and B may contain non-key variables with identical % names, JOIN ordinarily retains both copies in C. This % parameter specifies variables for which JOIN retains % only A's copy. 'KeepOneCopy' is a variable name or a % cell array containing one or more variable names. % Default is none. % % [C,IB] = JOIN(...) returns an index vector IB, where JOIN constructs C by % horizontally concatenating A(:,LEFTVARS) and B(IB,RIGHTVARS). % % Example: % % % Append values from one table to another using a simple join. % a = table({'John' 'Jane' 'Jim' 'Jerry' 'Jill'}',[1 2 1 2 1]', ... % 'VariableNames',{'Employee' 'Department'}) % b = table([1 2]',{'Mary' 'Mike'}','VariableNames',{'Department' 'Manager'}) % c = join(a,b) % % % Append values from one timetable to another timetable using a simple join. % Traffic = [0.8, 0.9, 0.1, 0.7, 0.9]; % Noise = [0, 1, 1.5, 2, 2.3]; % a = timetable(hours(1:5)',Traffic',Noise'); % % Distance = [0.88, 0.86, 0.91, 0.9, 0.86]; % b = timetable(hours(1:5)',Distance'); % c = join(a,b) % % % Append values from a table to a timetable. % Measurements = [0.13 0.22 0.31 0.42 0.53 0.57 0.67 0.81 0.90 1.00]; % Device = ['A';'B';'A';'B';'A';'B';'A';'B';'A';'B']; % a = timetable(seconds(1:10)', Measurements', Device); % % Device = ['A';'B']; % Accuracy = [0.023;0.037]; % b = table(Device, Accuracy); % c = join(a,b) % % See also INNERJOIN, OUTERJOIN, HORZCAT, SORTROWS, % UNION, INTERSECT, ISMEMBER, UNIQUE. % Copyright 2012-2016 The MathWorks, Inc. narginchk(2,inf); if ~matlab.internal.datatypes.istabular(a) || ~matlab.internal.datatypes.istabular(b) error(message('MATLAB:table:join:InvalidInput')); end if isa(a,'table') && isa(b,'timetable') % To join a timetable and table, the order must be specifically timetable first and table second error(message('MATLAB:table:join:TableTimetableInput')); end type = 'simple'; pnames = {'Keys' 'LeftKeys' 'RightKeys' 'LeftVariables' 'RightVariables' 'KeepOneCopy'}; dflts = { [] [] [] [] [] {} }; [keys,leftKeys,rightKeys,leftVars,rightVars,keepOneCopy,supplied] ... = matlab.internal.table.parseArgs(pnames, dflts, varargin{:}); [a,b,supplied,keys,leftKeys,rightKeys,leftVars,rightVars]... = prejoin(a,b,supplied,type,keys,leftKeys,rightKeys,leftVars,rightVars); if supplied.KeepOneCopy % The names in keepOneCopy must be valid var names, but need not actually match a % duplicated variable, or even any variable. if ~matlab.internal.datatypes.isCharStrings(keepOneCopy,false,false) % do not allow empty strings error(message('MATLAB:table:join:InvalidKeepOneCopy')); end try matlab.internal.tableUtils.makeValidName(keepOneCopy,'varnamesError'); % error if invalid catch error(message('MATLAB:table:join:InvalidKeepOneCopy')); end end [leftVars,rightVars,leftVarDim,rightVarDim,leftKeyVals,rightKeyVals,leftKeys,rightKeys] ... = tabular.joinUtil(a,b,type,inputname(1),inputname(2), ... keys,leftKeys,rightKeys,leftVars,rightVars,keepOneCopy,supplied); if leftKeys > 0 % Do the simple join C = [A(:,LEFTVARS) B(IB,RIGHTVARS)] by computing the row % indices into B for each row of C. The row indices into A are just 1:n. % Check that B's key contains no duplicates. if length(unique(rightKeyVals)) < size(rightKeyVals,1) error(message('MATLAB:table:join:DuplicateRightKeyVarValues')); end % Use the key vars to find indices from A into B, and make sure every % row in A has a corresponding one in B. try [tf,ir] = ismember(leftKeyVals,rightKeyVals); catch me error(message('MATLAB:table:join:KeyIsmemberMethodFailed', me.message)); end if ~isequal(size(tf),[length(leftKeyVals),1]) error(message('MATLAB:table:join:KeyIsmemberMethodReturnedWrongSize')); elseif any(~tf) nkeys = length(leftKeys); missingInA = ismissing(a); missingInA = missingInA(:,leftKeys); missingInB = ismissing(b); missingInB = missingInB(:,rightKeys); if any(missingInA(:)) || any(missingInB(:)) error(message('MATLAB:table:join:MissingKeyValues')); elseif nkeys == 1 error(message('MATLAB:table:join:LeftKeyValueNotFound')); else error(message('MATLAB:table:join:LeftKeyValuesNotFound')); end end else % leftKeyVals is 1:a.rowDim.length, rightKeyVals is a reordering of 1:b.rowDim.length ir = rightKeyVals; end % Create a new table by combining the specified variables from A with those % from B, the latter broadcasted out to A's length using the key variable % indices. c = a; % preserve all of a's per-array and per-row properties numLeftVars = length(leftVars); numRightVars = length(rightVars); c.data = [a.data(leftVars) cell(1,numRightVars)]; for j = 1:numRightVars var_j = b.data{rightVars(j)}; szOut = size(var_j); szOut(1) = a.rowDim.length; c.data{numLeftVars+j} = reshape(var_j(ir,:),szOut); end % Assign names and merge a's and b's per-var properties. c_varDim = leftVarDim.lengthenTo(numLeftVars+numRightVars,rightVarDim.labels); c.varDim = c_varDim.moveProps(rightVarDim,1:numRightVars,numLeftVars+(1:numRightVars)); c = postjoin(c,a,b,type,leftVarDim);