gusucode.com > datatypes 工具箱matlab源码程序 > datatypes/@tabular/vertcat.m
function t = vertcat(varargin) %VERTCAT Vertical concatenation for tables. % T = VERTCAT(T1, T2, ...) vertically concatenates the tables T1, T2, ... . % Row names, when present, must be unique across tables. VERTCAT fills % in default row names for the output when some of the inputs have names % and some do not. % % Variable names for all tables must be identical except for order. VERTCAT % concatenates by matching variable names. VERTCAT assigns values for each % property (except for RowNames) in T using the first non-empty value for % the corresponding property in the arrays T1, T2, ... . % % See also CAT, HORZCAT. % Copyright 2012-2016 The MathWorks, Inc. try nrows = zeros(1,nargin); for i = 1:nargin nrows(i) = size(varargin{i},1); % dispatch to overloaded size, not built-in end nrowsTotal = sum(nrows); t_nrows = 0; t_nvars = 0; % don't know yet needATable = true; for j = 1:nargin b = varargin{j}; wasCell = iscell(b); if matlab.internal.datatypes.istabular(b) % OK, avoid other checks elseif isequal(b,[]) % treat as "identity element", and ignore continue; elseif wasCell b = cell2table(b); % default var names won't be used else error(message('MATLAB:table:vertcat:InvalidInput')); end b_nvars = b.varDim.length; b_nrows = b.rowDim.length; rows_j = sum(nrows(1:j-1)) + (1:nrows(j)); if t_nvars==0 && t_nrows==0 % first input, or all previous inputs were 0x0 t = b; % preserve the subclass haveTime = isa(t,'timetable'); t_nvars = b_nvars; t_nrows = b_nrows; t_metaDim = b.metaDim; t_varDim = b.varDim; t_rowDim = b.rowDim.createLike(nrowsTotal); % empty labels t_arrayProps = b.arrayProps; needATable = wasCell; % use var/dim labels from a table, keep looking if a cell array [t_varLabelsSorted,t_varOrder] = sort(t_varDim.labels); b_data = cell(nargin,t_nvars); b_data(j,:) = b.data; elseif ~haveTime && isa(b,'timetable') % Tables can be concatenated onto a timetable, but not vice-versa error(message('MATLAB:table:vertcat:TableAndTimetable')); elseif b_nvars==0 && b_nrows==0 % special case to mimic built-in behavior % do nothing continue; elseif b_nvars ~= t_nvars error(message('MATLAB:table:vertcat:SizeMismatch')); else if wasCell % Assign positionally b_data(j,:) = b.data; else % was always a table if needATable t_metaDim = b.metaDim; t_varDim = b.varDim; [t_varLabelsSorted,t_varOrder] = sort(b.varDim.labels); needATable = false; b_data(j,:) = b.data; else %[tf,b_reord] = ismember(t.varDim.labels,b.varDim.labels); [b_varLabelsSorted,b_varOrder] = sort(b.varDim.labels); if ~isequal(t_varLabelsSorted,b_varLabelsSorted) error(message('MATLAB:table:vertcat:UnequalVarNames')); end b_reord(t_varOrder) = b_varOrder; %#ok<AGROW>, full reassignment each time b_data(j,:) = b.data(b_reord); t_varDim = t_varDim.mergeProps(b.varDim,b_reord); end end t_nrows = t_nrows + b_nrows; end % If it was originally a cell array, there are no row labels or other % properties to worry about. if ~wasCell % If it was originally a table/timetable, get its row labels % if any, unless it's a table being added to a timetable. if ~haveTime || ~isa(b,'table') try t_rowDim = t_rowDim.assignInto(b.rowDim,rows_j); catch ME if ~isequal(class(b.rowDim.labels),class(t_rowDim.labels)) t.throwSubclassSpecificError('RowLabelsTypeMismatch',class(b.rowDim.labels),class(t_rowDim.labels)); else rethrow(ME); end end end % Use any per-array property values not already present. t_arrayProps = mergeArrayProps(t_arrayProps,b.arrayProps); end end t_data = cell(1,t_nvars); for i = 1:t_nvars try t_data{i} = vertcat(b_data{:,i}); % []'s are dropped catch ME m = message('MATLAB:table:vertcat:VertcatMethodFailed',t.varDim.labels{i}); throw(addCause(MException(m.Identifier,'%s',getString(m)),ME)); end % Something went badly wrong with whatever vertcat method was called. if size(t_data{i},1) ~= t_nrows % One reason for this is concatenation of a cell variable with a non-cell % variable, which adds only a single cell to the former, containing the % latter. Check for cell/non-cell only after calling vertcat to allow % overloads such as categorical that can vertcat cell/non-cell sensibly. b_is0x0 = cellfun(@(c)isequal(size(c),[0 0]),varargin); % only check non-0x0 inputs cells = cellfun('isclass',b_data(~b_is0x0,i),'cell'); if any(cells) && ~all(cells) error(message('MATLAB:table:vertcat:VertcatCellAndNonCell', t.varDim.labels{i})); else error(message('MATLAB:table:vertcat:VertcatWrongLength', t.varDim.labels{i})); end end end t.data = t_data; t.metaDim = t_metaDim; t.varDim = t_varDim; if t_rowDim.hasLabels % Error if row labels are duplicates, and create default labels where labels are not present. t_rowDim = t_rowDim.setLabels(t_rowDim.labels,[],false,true); end t.rowDim = t_rowDim; t.arrayProps = t_arrayProps; catch ME throwAsCaller(ME) end