time | Calls | line |
---|
0.002 | 8 | 1 | classdef (AllowedSubclasses = {?timetable ?table}) tabular < matlab.mixin.internal.indexing.DotParen & matlab.internal.datatypes.saveLoadCompatibility
|
| | 2 | % Internal abstract superclass for table and timetable.
|
| | 3 | % This class is for internal use only and will change in a future release. Do not use this class.
|
| | 4 |
|
| | 5 | % Copyright 2016-2019 The MathWorks, Inc.
|
| | 6 |
|
| | 7 | properties(Constant, Access='protected') % *** may go back to private if every instance is in tabular
|
| | 8 | arrayPropsDflts = struct('Description', {''}, ...
|
| | 9 | 'UserData' , [],...
|
| | 10 | 'TableCustomProperties',struct);
|
| | 11 | end
|
| | 12 |
|
| | 13 | properties(Abstract, Constant, Access='protected')
|
| | 14 | % Constant properties are not persisted when serialized
|
| | 15 | propertyNames
|
| | 16 | defaultDimNames
|
| | 17 | dispRowLabelsHeader
|
| | 18 | emptyPropertiesObj
|
| | 19 | end
|
| | 20 |
|
| | 21 | properties(Abstract, Access='protected')
|
| | 22 | metaDim
|
| | 23 | rowDim
|
| | 24 | varDim
|
| | 25 | data
|
| | 26 | arrayProps
|
| | 27 | end
|
| | 28 |
|
| | 29 | properties(Dependent, SetAccess='protected')
|
| | 30 | %PROPERTIES Table or timetable metadata properties.
|
| | 31 | % T.Properties, where T is a table or a timetable, contains the
|
| | 32 | % following metadata:
|
| | 33 | %
|
| | 34 | % Description - A character vector describing the table
|
| | 35 | % UserData - A variable containing any additional information associated
|
| | 36 | % with the table. You can assign any value to this property.
|
| | 37 | % DimensionNames - A two-element cell array of character vectors containing names
|
| | 38 | % of the dimensions of the table
|
| | 39 | % VariableNames - A cell array containing names of the variables in the table
|
| | 40 | % VariableDescriptions - A cell array of character vectors containing descriptions of
|
| | 41 | % the variables in the table
|
| | 42 | % VariableUnits - A cell array of character vectors containing units for the
|
| | 43 | % variables in table
|
| | 44 | % RowNames (tables) - A cell array of nonempty, distinct character vectors containing
|
| | 45 | % names of the rows in the table
|
| | 46 | % RowTimes (timetables) - A datetime or durations vector containing times associated
|
| | 47 | % with each row in the timetable
|
| | 48 | % StartTime (timetables) - First time value in the timetable
|
| | 49 | % SampleRate (timetables) - For a timetable with a regularly-spaced time
|
| | 50 | % vector, the frequency of the samples
|
| | 51 | % TimeStep (timetables) - For a timetable with a regularly-spaced time
|
| | 52 | % vector, the time interval between samples
|
| | 53 | % CustomProperties - A container for user-defined per-table or per-variable custom
|
| | 54 | % metadata fields. Add custom properties using ADDPROP.
|
| | 55 | %
|
| | 56 | % See also TABLE, TIMETABLE, ADDPROP, RMPROP.
|
| | 57 | Properties
|
| | 58 | end
|
| | 59 | methods % dependent property get methods
|
| | 60 | function val = get.Properties(a)
|
| | 61 | val = getProperties(a);
|
| | 62 | end
|
| | 63 | end
|
| | 64 |
|
| | 65 | methods(Hidden)
|
| | 66 | function props = getProperties(t)
|
| | 67 | % This function is for internal use only and will change in a future release.
|
| | 68 | % Do not use this function. Use t.Properties instead.
|
| | 69 | import matlab.internal.datatypes.mergeScalarStructs
|
| | 70 | props = t.emptyPropertiesObj; % TableProperties or TimetableProperties
|
| | 71 |
|
| | 72 | p = mergeScalarStructs(t.arrayProps, ...
|
| | 73 | t.metaDim.getProperties(), ...
|
| | 74 | t.varDim.getProperties(), ...
|
| | 75 | t.rowDim.getProperties());
|
| | 76 | p.CustomProperties = matlab.tabular.CustomProperties(...
|
| | 77 | p.TableCustomProperties,...
|
| | 78 | p.VariableCustomProperties);
|
| | 79 | p = rmfield(p,["VariableCustomProperties","TableCustomProperties"]);
|
| | 80 | f = fieldnames(p);
|
| | 81 | for i = 1:numel(f)
|
| | 82 | props.(f{i}) = p.(f{i});
|
| | 83 | end
|
| | 84 | end
|
| | 85 |
|
| | 86 | function t = setProperties(t,s)
|
| | 87 | %SET Set some or all table properties from a scalar struct or properties object.
|
| | 88 | % This function is for internal use only and will change in a future release.
|
| | 89 | % Do not use this function. Use t.Properties instead.
|
| | 90 | if isstruct(s) && isscalar(s)
|
| | 91 | fnames = fieldnames(s);
|
| | 92 | elseif isa(s, class(t.emptyPropertiesObj))
|
| | 93 | fnames = properties(s);
|
| | 94 | else
|
| | 95 | error(message('MATLAB:table:InvalidPropertiesAssignment',class(t.emptyPropertiesObj),class(t)));
|
| | 96 | end
|
| | 97 |
|
| | 98 | for i = 1:length(fnames)
|
| | 99 | fn = fnames{i};
|
| | 100 | t = t.setProperty(fn,s.(fn));
|
| | 101 | end
|
| | 102 | end
|
| | 103 |
|
| | 104 | % Allows tab completion after dot to suggest variables
|
| | 105 | function p = properties(t)
|
| | 106 | % This will be called for properties of an instance, but the built-in will
|
| | 107 | % still be called for the class name. It will return just Properties,
|
| | 108 | % which is correct.
|
| | 109 |
|
| | 110 | pp = [t.varDim.labels(:); 'Properties'; t.metaDim.labels(:)];
|
| | 111 | if nargout == 0
|
| | 112 | % get 1 or 0 newlines based on format loose/compact
|
| | 113 | line_ending = repmat(newline,1,strcmp(matlab.internal.display.formatSpacing,'loose'));
|
| | 114 | fprintf([line_ending '%s\n' line_ending], getString(message('MATLAB:ClassUstring:PROPERTIES_FUNCTION_LABEL',class(t))));
|
| | 115 | fprintf(' %s\n',pp{:});
|
| | 116 | fprintf(line_ending);
|
| | 117 | else
|
| | 118 | p = pp;
|
| | 119 | end
|
| | 120 | end
|
| | 121 | function f = fieldnames(t), f = properties(t); end
|
| | 122 | function f = fields(t), f = properties(t); end
|
| | 123 |
|
| | 124 | function vars = getVars(t,asStruct)
|
| | 125 | % This function is for internal use only and will change in a future release.
|
| | 126 | % Do not use this function. Use table2struct(t,'AsScalar',true) instead.
|
| | 127 | if nargin < 2 || asStruct
|
| | 128 | [fnames, fixed] = t.varDim.makeValidName(t.varDim.labels,'warn');
|
| | 129 | fnames = matlab.lang.makeUniqueStrings(fnames, fixed,namelengthmax);
|
| | 130 | vars = cell2struct(t.data,fnames,2);
|
| | 131 | else
|
| | 132 | vars = t.data;
|
| | 133 | end
|
| | 134 | end
|
| | 135 |
|
| | 136 | function n = getCustomPropertyNames(t)
|
| | 137 | % Used in tab completion for rmprop.
|
| | 138 | n = [fieldnames(t.varDim.customProps); fieldnames(t.arrayProps.TableCustomProperties)]';
|
| | 139 | end
|
| | 140 |
|
| | 141 | function t1 = transferNonRowProperties(t,t1)
|
| | 142 | % This function is for internal use only and will change in a future release.
|
| | 143 | % Do not use this function. Used by table2timetable.
|
| | 144 | f = fieldnames(t.arrayProps);
|
| | 145 | for ii = 1:numel(f)
|
| | 146 | t1.arrayProps.(f{ii}) = t.arrayProps.(f{ii});
|
| | 147 | end
|
| | 148 | t_varDim = t.varDim;
|
| | 149 | t1.varDim = t1.varDim.init(t_varDim.length,t_varDim.labels,t_varDim.descrs,t_varDim.units,t_varDim.continuity,t_varDim.customProps);
|
| | 150 | end
|
| | 151 |
|
| | 152 | function [indices,isLabels] = subs2inds(t,subs,subsType,dim)
|
| | 153 | % This function is for internal use only and will change in a future release.
|
| | 154 | % Do not use this function.
|
| | 155 | switch subsType
|
| | 156 | case 'assignment'
|
| | 157 | sType = matlab.internal.tabular.private.tabularDimension.subsType.assignment;
|
| | 158 | case 'reference'
|
| | 159 | sType = matlab.internal.tabular.private.tabularDimension.subsType.reference;
|
| | 160 | case 'deletion'
|
| | 161 | sType = matlab.internal.tabular.private.tabularDimension.subsType.deletion;
|
| | 162 | end
|
| | 163 | switch dim
|
| | 164 | case 'varDim'
|
| | 165 | [indices,~,~,~,isLabels] = t.varDim.subs2inds(subs,sType,t.data);
|
| | 166 | case 'rowDim'
|
| | 167 | [indices,~,~,~,isLabels] = t.rowDim.subs2inds(subs,sType);
|
| | 168 | case 'metaDim'
|
| | 169 | [indices,~,~,~,isLabels] = t.metaDim.subs2inds(subs,sType);
|
| | 170 | end
|
| | 171 | end
|
| | 172 |
|
| | 173 | % Methods we don't want to clutter things up with
|
| | 174 | e = end(t,k,n)
|
| | 175 | B = repelem(A,M,N,varargin)
|
| | 176 | disp(t,bold,indent,fullChar,nestedLevel)
|
| | 177 | display(obj, name)
|
| | 178 | [varargout] = subsref(t,s)
|
| | 179 | t = subsasgn(t,s,b)
|
| | 180 |
|
| | 181 | % These functions are for internal use only and will change in a
|
| | 182 | % future release. Do not use these functions.
|
| | 183 | b = dotParenReference(t,vn,s1,s2,varargin)
|
| | 184 | sz = numArgumentsFromSubscript(t,s,context)
|
| | 185 | [vars,varData,sortMode,varargout] = sortrowsFlagChecks(t,doIssortedrows,vars,sortMode,varargin)
|
| | 186 | [vars,varData,sortMode,labels,varargin] = topkrowsFlagChecks(a,vars,sortMode,varargin)
|
| | 187 |
|
| | 188 | %% Variable Editor methods
|
| | 189 | % These functions are for internal use only and will change in a
|
| | 190 | % future release. Do not use these functions.
|
| | 191 | varargout = variableEditorGridSize(t)
|
| | 192 | [names,indices,classes,iscellstr,charArrayWidths] = variableEditorColumnNames(t)
|
| | 193 | rowNames = variableEditorRowNames(t)
|
| | 194 | [code,msg] = variableEditorRowDeleteCode(t,workspaceVariableName,rowIntervals)
|
| | 195 | [code,msg] = variableEditorColumnDeleteCode(t,workspaceVariableName,columnIntervals)
|
| | 196 | t = variableEditorPaste(t,rows,columns,data)
|
| | 197 | t = variableEditorInsert(t,orientation,row,col,data)
|
| | 198 | [code,msg] = variableEditorSetDataCode(t,workspaceVariableName,row,col,rhs)
|
| | 199 | [code,msg] = variableEditorUngroupCode(t,varName,col)
|
| | 200 | [code,msg] = variableEditorGroupCode(t,varName,startCol,endCol)
|
| | 201 | metaData = variableEditorMetadata(t)
|
| | 202 | [code,msg] = variableEditorMetadataCode(t,varName,index,propertyName,propertyString)
|
| | 203 | [code,msg] = variableEditorRowNameCode(t,varName,index,rowName)
|
| | 204 | [code,msg] = variableEditorSortCode(t,varName,tableVariableNames,direction)
|
| | 205 | [code,msg] = variableEditorMoveColumn(t,varName,startCol,endCol)
|
| | 206 |
|
| | 207 | %% Error stubs
|
| | 208 | % Methods to override functions and throw helpful errors
|
| | 209 | function d = double(t,varargin), throwInvalidNumericConversion(t); end %#ok<STOUT>
|
| | 210 | function s = single(t,varargin), throwInvalidNumericConversion(t); end %#ok<STOUT>
|
| | 211 | function n = length(t,varargin), error(message('MATLAB:table:UndefinedLengthFunction',class(t))); end %#ok<STOUT>
|
| | 212 | function t = transpose(t,varargin), throwUndefinedTransposeError(t); end
|
| | 213 | function t = ctranspose(t,varargin), throwUndefinedTransposeError(t); end
|
| | 214 | function t = permute(t,varargin), throwUndefinedError(t); end
|
| | 215 | function t = reshape(t,varargin), throwUndefinedError(t); end
|
| | 216 | function t = plot(t,varargin), error(message('MATLAB:table:NoPlotMethod')); end %#ok<INUSD>
|
| | 217 |
|
| | 218 | function t = sort(t,varargin)
|
| | 219 | import matlab.lang.correction.ReplaceIdentifierCorrection
|
| | 220 | throw(MException(message('MATLAB:table:UndefinedSortFunction',class(t))) ...
|
| | 221 | .addCorrection(ReplaceIdentifierCorrection('sort','sortrows')));
|
| | 222 | end
|
| | 223 | end % hidden methods block
|
| | 224 |
|
| | 225 | methods(Abstract, Hidden, Static)
|
| | 226 | t = empty(varargin)
|
| | 227 |
|
| | 228 | % These functions are for internal use only and will change in a
|
| | 229 | % future release. Do not use these functions.
|
| | 230 | t = fromScalarStruct(s)
|
| | 231 | t = init(vars, numRows, rowLabels, numVars, varnames)
|
| | 232 | end % abstract hidden static methods block
|
| | 233 |
|
| | 234 | methods(Access = 'protected')
|
| | 235 | t = setDescription(t,newDescr)
|
| | 236 | t = setUserData(t,newData)
|
| | 237 |
|
| | 238 | [varargout] = subsrefParens(t,s)
|
| | 239 | [varargout] = subsrefBraces(t,s)
|
| | 240 | [varargout] = subsrefDot(t,s)
|
| | 241 | t = subsasgnParens(t,s,b,creating,deleting)
|
| | 242 | t = subsasgnBraces(t,s,b)
|
| | 243 | t = subsasgnDot(t,s,b,deleting)
|
| | 244 |
|
| | 245 | b = extractData(t,vars,like,a)
|
| | 246 | t = replaceData(t,x,vars)
|
| | 247 |
|
| | 248 | varIndices = getVarOrRowLabelIndices(t,varSubscripts,allowEmptyRowLabels)
|
| | 249 | varData = getVarOrRowLabelData(t,varIndices,warnMsg)
|
| | 250 | [group,glabels,glocs] = table2gidx(a,avars,reduce)
|
| | 251 | varIndex = subs2indsErrorHandler(a,varName,ME,callerID)
|
| | 252 |
|
| | 253 | function errID = throwSubclassSpecificError(~,msgid,varargin)
|
| | 254 | % THROWSUBCLASSSPECIFICERROR is called by overloads in the subclasses and returns an
|
| | 255 | % MException that is specific to the subclass which can then be returned to the
|
| | 256 | % caller or thrown.
|
| | 257 | try
|
| | 258 | errID = MException(message(['MATLAB:' msgid],varargin{:}));
|
| | 259 | catch ME
|
| | 260 | if strcmp(ME.identifier,'MATLAB:builtins:MessageNotFound')
|
| | 261 | % This function should never be called with a non-existent ID
|
| | 262 | assert(false);
|
| | 263 | else
|
| | 264 | rethrow(ME);
|
| | 265 | end
|
| | 266 | end
|
| | 267 | end
|
| | 268 |
|
| | 269 | function t = initInternals(t, vars, nrows, rowLabels, nvars, varnames)
|
| | 270 | % INITINTERNALS Fills an empty tabular object with data and dimension objects. This
|
| | 271 | % function is for internal use only and will change in a future release. Do not use
|
| | 272 | % this function.
|
| | 273 | try
|
| | 274 | t.rowDim = t.rowDim.createLike(nrows,rowLabels);
|
| | 275 | t.varDim = t.varDim.createLike(nvars,varnames); % error if invalid, duplicate, or empty
|
| | 276 | t.data(1,1:nvars) = vars; % force 1xN, and hard error if vars is the wrong length
|
| | 277 | catch ME
|
| | 278 | throwAsCaller(ME)
|
| | 279 | end
|
| | 280 | end
|
| | 281 |
|
| | 282 | function t = rmPerTableProperty(t, names)
|
| | 283 | t.arrayProps.TableCustomProperties = rmfield(t.arrayProps.TableCustomProperties, names);
|
| | 284 | end
|
| | 285 |
|
| | 286 | function t = setPerTableProperty(t, newProps,name)
|
| | 287 | t.arrayProps.TableCustomProperties.(name) = newProps;
|
| | 288 | end
|
| | 289 | end % protected methods block
|
| | 290 |
|
| | 291 | methods(Abstract, Access = 'protected')
|
| | 292 | b = cloneAsEmpty(a)
|
| | 293 |
|
| | 294 | % Used by summary method
|
| | 295 | rowLabelsStruct = summarizeRowLabels(t);
|
| | 296 | printRowLabelsSummary(t,rowLabelsStruct);
|
| | 297 |
|
| | 298 | % Used by varfun and rowfun
|
| | 299 | id = specifyInvalidOutputFormatID(t,funName);
|
| | 300 | end % abstract protected methods block
|
| | 301 |
|
| | 302 | methods(Access = 'private')
|
| | 303 | varIndex = getGroupingVarOrTime(t,varName)
|
| | 304 | [varargout] = getProperty(t,name,createIfEmpty)
|
| | 305 | t = setProperty(t,name,p)
|
| | 306 | t = lengthenTo(t,newLen)
|
| | 307 | end
|
| | 308 |
|
| | 309 | methods (Static, Hidden)
|
| | 310 | vars = container2vars(c)
|
| | 311 | t = primitiveHorzcat(t,varargin)
|
| | 312 | b = lengthenVar(a,n)
|
| | 313 |
|
| | 314 | function name = matlabCodegenRedirect(~)
|
| | 315 | % Use the implementation in the class below when generating
|
| | 316 | % code.
|
| | 317 | name = 'matlab.internal.coder.tabular';
|
| | 318 | end
|
| | 319 | end % static hidden methods block
|
| | 320 |
|
| | 321 | methods(Static, Access = 'protected')
|
| | 322 | [ainds,binds] = table2midx(a,b)
|
| | 323 | [leftKeys,rightKeys] = joinKeys(a,b,keys,leftKeys,rightKeys,supplied)
|
| | 324 | [leftVars,rightVars,leftVarDim,rightVarDim,leftKeyVals,rightKeyVals,leftKeys,rightKeys] ...
|
| | 325 | = joinUtil(a,b,type,leftTableName,rightTableName, ...
|
| | 326 | keys,leftKeys,rightKeys,leftVars,rightVars,keepOneCopy,supplied,merge)
|
| | 327 | [c,il,ir] = joinInnerOuter(a,b,leftOuter,rightOuter,leftKeyvals,rightKeyvals, ...
|
| | 328 | leftVars,rightVars,leftKeys,rightKeys,leftVarnames,rightVarnames, ...
|
| | 329 | mergeKeyProps)
|
| | 330 | a_arrayProps = mergeArrayProps(a_arrayProps,b_arrayProps) % Used by both table and timetable
|
| | 331 |
|
| | 332 | function [numVars, numRows] = countVarInputs(args,StringParamNameNotSupportedErrID)
|
| | 333 | %COUNTVARINPUTS Count the number of data vars from a tabular input arg list
|
| | 334 | import matlab.internal.datatypes.isCharString
|
| | 335 | argCnt = 0;
|
| | 336 | numVars = 0;
|
| | 337 | numRows = 0;
|
| | 338 | while argCnt < length(args)
|
| | 339 | argCnt = argCnt + 1;
|
| | 340 | arg = args{argCnt};
|
| | 341 | if isCharString(arg) % Matches any character row vector (including ''), not just a parameter name
|
| | 342 | % Put that one back and start processing param name/value pairs
|
| | 343 | argCnt = argCnt - 1; %#ok<NASGU>
|
| | 344 | break
|
| | 345 | elseif isa(arg,'function_handle')
|
| | 346 | throwAsCaller(MException(message('MATLAB:table:FunAsVariable')));
|
| | 347 | else % an array that will become a variable in t
|
| | 348 | numVars = numVars + 1;
|
| | 349 | end
|
| | 350 | numRows_j = size(arg,1);
|
| | 351 | if argCnt == 1
|
| | 352 | numRows = numRows_j;
|
| | 353 | elseif ~isequal(numRows_j,numRows)
|
| | 354 | ME = MException(message('MATLAB:table:UnequalVarLengths'));
|
| | 355 | if isstring(arg) && isscalar(arg) && numRows > 1
|
| | 356 | % A scalar string following inputs with more than one row
|
| | 357 | % is likely intended as a parameter name, give a helpful
|
| | 358 | % error.
|
| | 359 | cause = MException(message(StringParamNameNotSupportedErrID,arg));
|
| | 360 | ME = ME.addCause(cause);
|
| | 361 | end
|
| | 362 | throwAsCaller(ME);
|
| | 363 | end
|
| | 364 | end % while argCnt < numArgs, processing individual vars
|
| | 365 | end
|
| | 366 |
|
| | 367 | function [nrows,nvars] = validateVarHeights(vars)
|
| | 368 | %VALIDATEVARROWS Validate a cell array of prospective table variables
|
| | 369 | nvars = length(vars);
|
| | 370 | if nvars > 0
|
| | 371 | % Check that variables are the same height.
|
| | 372 | nrows = size(vars{1},1);
|
| | 373 | for i = 1:nvars
|
| | 374 | if size(vars{i},1) ~= nrows
|
| | 375 | error(message('MATLAB:table:UnequalFieldLengths'));
|
| | 376 | end
|
| | 377 | end
|
| | 378 | else
|
| | 379 | nrows = 0;
|
| | 380 | end
|
| | 381 | end
|
| | 382 |
|
| | 383 | function vars = createVariables(types,sz)
|
| | 384 | % Create variables of the specified types, of the specified height,
|
| | 385 | % for a preallocated table, filled with each type's default value.
|
| | 386 | nrows = sz(1);
|
| | 387 | nvars = sz(2);
|
| | 388 | vars = cell(1,nvars); % a row vector
|
| | 389 | for ii = 1:nvars
|
| | 390 | type = types{ii};
|
| | 391 | switch type
|
| | 392 | case {'double' 'single' 'logical'}
|
| | 393 | vars{ii} = zeros(nrows,1,type);
|
| | 394 | case {'doublenan' 'doubleNaN' 'singlenan' 'singleNaN'}
|
| | 395 | vars{ii} = NaN(nrows,1,extractBefore(lower(type),'nan'));
|
| | 396 | case 'string'
|
| | 397 | vars{ii} = repmat(string(missing),nrows,1);
|
| | 398 | case 'cell'
|
| | 399 | vars{ii} = cell(nrows,1);
|
| | 400 | case 'datetime'
|
| | 401 | vars{ii} = datetime.fromMillis(NaN(nrows,1));
|
| | 402 | case 'duration'
|
| | 403 | vars{ii} = duration.fromMillis(zeros(nrows,1));
|
| | 404 | case 'calendarDuration'
|
| | 405 | vars{ii} = calendarDuration(zeros(nrows,1),0,0);
|
| | 406 | case 'categorical'
|
| | 407 | vars{ii} = categorical(NaN(nrows,1));
|
| | 408 | case {'int8' 'int16' 'int32' 'int64' 'uint8' 'uint16' 'uint32' 'uint64'}
|
| | 409 | vars{ii} = zeros(nrows,1,type);
|
| | 410 | case {'cellstr' 'char'}
|
| | 411 | if strcmp(type,'char')
|
| | 412 | % Special case: replace 'char' with 'cellstr', with a warning. A char
|
| | 413 | % array is tempting but not a good choice for text data in a table.
|
| | 414 | matlab.internal.datatypes.warningWithoutTrace(message('MATLAB:table:PreallocateCharWarning'));
|
| | 415 | end
|
| | 416 | % cellstr is a special case that's not actually a type name.
|
| | 417 | vars{ii} = repmat({''},nrows,1);
|
| | 418 | otherwise
|
| | 419 | if nrows > 0 % lengthenVar requires n > 0
|
| | 420 | % Use lengthenVar to create a var of the correct height. Not
|
| | 421 | % all types have their name as a constructor, e.g. double.
|
| | 422 | % So instead of creating a scalar instance to lengthen,
|
| | 423 | % create an empty instance.
|
| | 424 | try
|
| | 425 | % Create 0x0, lengthenVar will turn it into an Nx1, but
|
| | 426 | % would turn a 1x0 into an Nx0 empty.
|
| | 427 | emptyVar = eval([type '.empty(0,0)']);
|
| | 428 | catch ME
|
| | 429 | throwAsCaller(preallocationClassErrorException(ME,type));
|
| | 430 | end
|
| | 431 | % lengthenVar creates an instance of var_ii that is nrows-by-1,
|
| | 432 | % filled in with the default (not necessarily "missing") value.
|
| | 433 | try
|
| | 434 | vars{ii} = tabular.lengthenVar(emptyVar,nrows);
|
| | 435 | catch
|
| | 436 | % lengthenVar failed, but we can still create an nrows-by-0 instance.
|
| | 437 | vars{ii} = eval([type '.empty(nrows,0)']); % don't use reshape, may not be one
|
| | 438 | end
|
| | 439 | else
|
| | 440 | try
|
| | 441 | vars{ii} = eval([type '.empty(0,1)']);
|
| | 442 | catch ME
|
| | 443 | throwAsCaller(preallocationClassErrorException(ME,type));
|
| | 444 | end
|
| | 445 | end
|
| | 446 | end
|
| | 447 | end
|
| | 448 | end
|
| | 449 |
|
| | 450 | function s = handleFailedToLoadVars(s,numRows,numVars,varNames)
|
| | 451 | % Detect if some variables failed to load and replace those
|
| | 452 | % variables with numRows-by-0 empty double
|
| | 453 |
|
| | 454 | % Tabular variables always have the same consistent number of
|
| | 455 | % rows. When a variable's number of rows is inconsistent with
|
| | 456 | % numRows, the variable _must_ have failed to load properly --
|
| | 457 | % likely because the class is not defined in loading session.
|
| | 458 | % Replace data in failed-to-load variables with numRows-by-0
|
| | 459 | % empty double to maintain integrity of the tabular instance
|
| | 460 | isVarNumRowsMismatch = false(1,numVars);
|
| | 461 | for i = 1:numVars
|
| | 462 | isVarNumRowsMismatch(i) = (size(s.data{i},1)~=numRows);
|
| | 463 | end
|
| | 464 |
|
| | 465 | if any(isVarNumRowsMismatch)
|
| | 466 | s.data(isVarNumRowsMismatch) = {zeros(numRows,0)};
|
| | 467 |
|
| | 468 | if (nnz(isVarNumRowsMismatch)==1)
|
| | 469 | matlab.internal.datatypes.warningWithoutTrace(message('MATLAB:tabular:CannotLoadVariable',varNames{isVarNumRowsMismatch}));
|
| | 470 | else
|
| | 471 | matlab.internal.datatypes.warningWithoutTrace(message('MATLAB:tabular:CannotLoadVariables'));
|
| | 472 | end
|
| | 473 | end
|
| | 474 | end
|
| | 475 | end % static protected methods block
|
| | 476 |
|
| | 477 | methods(Static, Access = 'private')
|
| | 478 | name = matchPropertyName(name,propertyNames,exact)
|
| | 479 | flag = setmembershipFlagChecks(varargin)
|
| | 480 | args = processSetMembershipFlags(varargin)
|
| | 481 | var = writetableMatricize(var)
|
| | 482 | end % static private methods block
|
| | 483 |
|
| | 484 | %%%%% TEST HOOKS BLOCK allows unit testing for protected methods. %%%%%
|
| | 485 | %%%%% Methods in this block are for internal use only and will change %
|
| | 486 | %%%%% in a future release. Do not use these methods. %%%%%%%%%%%%%%%%%%
|
| | 487 | methods(Access = ?matlab.unittest.TestCase)
|
| | 488 | function b = extractDataTestHook(t,vars)
|
| | 489 | b = extractData(t,vars);
|
| | 490 | end
|
| | 491 |
|
| | 492 | function [group,glabels,glocs] = table2gidxTestHook(a, avars, reduce)
|
| | 493 | if nargin < 3, reduce = true; end
|
| | 494 | [group,glabels,glocs] = table2gidx(a,avars,reduce);
|
| | 495 | end
|
| | 496 | end
|
| | 497 |
|
| | 498 | methods(Static, Access = ?matlab.unittest.TestCase)
|
| | 499 | function methodList = methodsWithNonTabularFirstArgument, methodList = {'cat','rowfun','varfun'}; end
|
| | 500 | end % test hooks block
|
| | 501 |
|
| | 502 |
|
| | 503 | %%%%% PERSISTENCE BLOCK ensures correct save/load across releases %%%%%
|
| | 504 | %%%%% Properties and methods in this block maintain the exact class %%%
|
| | 505 | %%%%% schema required for TABULAR to persist through MATLAB releases %%
|
| | 506 | methods (Hidden)
|
| | 507 | function s = saveobj(t,s)
|
| | 508 | if (nargin == 1), s = struct; end
|
| | 509 |
|
| | 510 | s.CustomProps = t.arrayProps.TableCustomProperties;
|
| | 511 | s.VariableCustomProps = t.varDim.customProps;
|
| | 512 | end
|
| | 513 | end
|
| | 514 | end % classdef
|
| | 515 |
|
| | 516 | %-----------------------------------------------------------------------------
|
| | 517 | function throwUndefinedError(obj,varargin)
|
| | 518 | st = dbstack;
|
| | 519 | name = regexp(st(2).name,'\.','split');
|
| | 520 | throwAsCaller(MException(message('MATLAB:table:UndefinedFunction',name{2},class(obj))));
|
| | 521 | end % function
|
| | 522 |
|
| | 523 | %-----------------------------------------------------------------------------
|
| | 524 | function throwUndefinedTransposeError(obj)
|
| | 525 | import matlab.lang.correction.ReplaceIdentifierCorrection
|
| | 526 | st = dbstack;
|
| | 527 | name = regexp(st(2).name,'\.','split');
|
| | 528 | throwAsCaller(MException(message('MATLAB:table:UndefinedTransposeFunction',name{2},class(obj))) ...
|
| | 529 | .addCorrection(ReplaceIdentifierCorrection(name{2},'rows2vars')));
|
| | 530 | end % function
|
| | 531 |
|
| | 532 | %-----------------------------------------------------------------------------
|
| | 533 | function throwInvalidNumericConversion(obj,varargin)
|
| | 534 | import matlab.lang.correction.ReplaceIdentifierCorrection
|
| | 535 | st = dbstack;
|
| | 536 | name = regexp(st(2).name,'\.','split');
|
| | 537 | throwAsCaller(MException(message('MATLAB:table:InvalidNumericConversion',name{2},class(obj))) ...
|
| | 538 | .addCorrection(ReplaceIdentifierCorrection(name{2},'table2array')));
|
| | 539 | end % function
|
| | 540 |
|
| | 541 | %-----------------------------------------------------------------------------
|
| | 542 | function ME = preallocationClassErrorException(ME,type)
|
| | 543 | if strcmp(ME.identifier,'MATLAB:undefinedVarOrClass')
|
| | 544 | theMatch = matlab.internal.language.introspective.safeWhich(type,false);
|
| | 545 | if isempty(theMatch)
|
| | 546 | ME = MException(message('MATLAB:table:PreAllocationUndefinedClass',type));
|
| | 547 | else
|
| | 548 | [~,theMatch,~] = fileparts(theMatch);
|
| | 549 | ME = MException(message('MATLAB:table:PreAllocationClassnameCase',type,theMatch));
|
| | 550 | end
|
| | 551 | else
|
| | 552 | ME = MException(message('MATLAB:table:InvalidPreallocationVariableType',type,ME.message));
|
| | 553 | end
|
| | 554 | end % function
|
| | 555 |
|