time | Calls | line |
---|
| | 1 | function t = subsasgnParens(t,s,b,creating,deleting)
|
| | 2 | %SUBSASGNPARENS Subscripted assignment to a table.
|
| | 3 |
|
| | 4 | % Copyright 2012-2019 The MathWorks, Inc.
|
| | 5 |
|
| | 6 | import matlab.internal.datatypes.defaultarrayLike
|
| | 7 | import matlab.internal.datatypes.matricize
|
| | 8 | import matlab.internal.datatypes.isColon
|
| | 9 | import matlab.lang.internal.move % Avoid unsharing of shared-data copy across function call boundary
|
0.001 | 1292 | 10 | subsType = matlab.internal.tabular.private.tabularDimension.subsType; % "import" for calls to subs2inds
|
| | 11 |
|
| | 12 | % '()' is assignment to a subset of a table. Only dot subscripting
|
| | 13 | % may follow.
|
| | 14 |
|
< 0.001 | 1292 | 15 | if nargin < 4, creating = false; end
|
< 0.001 | 1292 | 16 | if ~isstruct(s), s = substruct('()',s); end
|
| | 17 |
|
0.005 | 1292 | 18 | if numel(s(1).subs) ~= t.metaDim.length
|
| | 19 | error(message('MATLAB:table:NDSubscript'));
|
< 0.001 | 1292 | 20 | end
|
| | 21 |
|
< 0.001 | 1292 | 22 | if ~isscalar(s)
|
| | 23 | switch s(2).type
|
| | 24 | case '()'
|
| | 25 | error(message('MATLAB:table:InvalidSubscriptExpr'));
|
| | 26 | case '{}'
|
| | 27 | error(message('MATLAB:table:InvalidSubscriptExpr'));
|
| | 28 | case '.'
|
| | 29 | if creating
|
| | 30 | error(message('MATLAB:table:InvalidSubscriptExpr'));
|
| | 31 | end
|
| | 32 |
|
| | 33 | % Syntax: t(rowIndices,varIndices).name = b
|
| | 34 | % Syntax: t(rowIndices,varIndices).name(...) = b
|
| | 35 | % Syntax: t(rowIndices,varIndices).name{...} = b
|
| | 36 | % Syntax: t(rowIndices,varIndices).name.field = b
|
| | 37 | %
|
| | 38 | % Assignment into a variable of a subarray.
|
| | 39 | %
|
| | 40 | % This may also be followed by deeper levels of subscripting.
|
| | 41 | %
|
| | 42 | % t(rowIndices,varIndices) must refer to rows and vars that exist, and
|
| | 43 | % the .name assignment can't add rows or refer to a new variable. This
|
| | 44 | % is to prevent cases where the indexing beyond t(rowIndices,varIndices)
|
| | 45 | % refers to things that are new relative to that subarray, but which
|
| | 46 | % already exist in t itself. So, cannot grow the table by an assignment
|
| | 47 | % like this.
|
| | 48 | %
|
| | 49 | % This can be deletion, but it must be "inside" a variable, and not
|
| | 50 | % change the size of t(rowIndices,varIndices).
|
| | 51 |
|
| | 52 | % Get the subarray, do the dot-variable assignment on that.
|
| | 53 | try
|
| | 54 | % this creates a shared-copy reference to the referenced subarray
|
| | 55 | % and leads to memory copying (i.e. unsharing) when the subarray
|
| | 56 | % is assigned into. In theory, since the updated subarray is
|
| | 57 | % subsequentyly assigned back into t, this should be done
|
| | 58 | % in-place (i.e. no memory copy); in practice, this
|
| | 59 | % optimization is viable as it is not possible to eliminate the
|
| | 60 | % original shared-copy reference on the subarray
|
| | 61 | c = t.subsrefParens(s(1));
|
| | 62 | catch ME
|
| | 63 | outOfRangeIDs = ["MATLAB:table:RowIndexOutOfRange" "MATLAB:table:UnrecognizedRowName" ...
|
| | 64 | "MATLAB:table:VarIndexOutOfRange" "MATLAB:table:UnrecognizedVarName"];
|
| | 65 | matlab.internal.datatypes.throwInstead(ME,outOfRangeIDs,"MATLAB:table:InvalidExpansion")
|
| | 66 | end
|
| | 67 |
|
| | 68 | % Assigning to .Properties of a subarray is not allowed.
|
| | 69 | if strcmp(s(2).subs, "Properties")
|
| | 70 | error(message('MATLAB:table:PropertiesAssignmentToSubarray'));
|
| | 71 | end
|
| | 72 |
|
| | 73 | % Check numeric before builtin to short-circuit for performance and
|
| | 74 | % to distinguish between '' and [].
|
| | 75 | nestedDeleting = isnumeric(b) && builtin('_isEmptySqrBrktLiteral',b);
|
| | 76 | cSize = size(c);
|
| | 77 | b = move(c).subsasgnDot(s(2:end),b);
|
| | 78 |
|
| | 79 | % Changing the size of the subarray -- growing it by assignment or
|
| | 80 | % deleting part of it -- is not allowed.
|
| | 81 | if ~isequal(size(b),cSize)
|
| | 82 | if nestedDeleting
|
| | 83 | error(message('MATLAB:table:EmptyAssignmentToSubarrayVar'));
|
| | 84 | else
|
| | 85 | error(message('MATLAB:table:InvalidExpansion'));
|
| | 86 | end
|
| | 87 | end
|
| | 88 |
|
| | 89 | % Now let the simple () subscripting code handle assignment of the updated
|
| | 90 | % subarray back into the original array.
|
| | 91 | s = s(1);
|
| | 92 | end
|
< 0.001 | 1292 | 93 | end
|
| | 94 |
|
| | 95 | % If the RHS is (still) [], we are deleting a variable from the table.
|
< 0.001 | 1292 | 96 | if nargin < 5
|
0.003 | 1292 | 97 | deleting = isnumeric(b) && builtin('_isEmptySqrBrktLiteral',b);
|
< 0.001 | 1292 | 98 | end
|
| | 99 |
|
< 0.001 | 1292 | 100 | t_nrowsExisting = t.rowDim.length;
|
< 0.001 | 1292 | 101 | t_nvarsExisting = t.varDim.length;
|
< 0.001 | 1292 | 102 | assigningInto0x0 = (t_nrowsExisting+t_nvarsExisting == 0); % all(size(t) == 0)
|
< 0.001 | 1292 | 103 | creatingOrAssigningInto0x0 = ~deleting && (creating || assigningInto0x0);
|
< 0.001 | 1292 | 104 | isTabularRHS = isa(b,'tabular');
|
< 0.001 | 1292 | 105 | if isTabularRHS
|
< 0.001 | 1292 | 106 | b_nrows = b.rowDim.length;
|
< 0.001 | 1292 | 107 | b_nvars = b.varDim.length;
|
| | 108 | else
|
| | 109 | [b_nrows,b_nvars] = size(b);
|
< 0.001 | 1292 | 110 | end
|
| | 111 |
|
< 0.001 | 1292 | 112 | if creatingOrAssigningInto0x0
|
| | 113 | % First sort out the row subscript, and copy the RHS's row labels
|
| | 114 | % as appropriate
|
| | 115 | if isColon(s(1).subs{1}) % t(:,...) = b
|
| | 116 | % When creating a new tabular, or growing from 0x0, interpret a ':' rows
|
| | 117 | % subscript with respect to the RHS, not as nothing.
|
| | 118 | rowIndices = 1:b_nrows;
|
| | 119 | numRowIndices = b_nrows;
|
| | 120 | maxRowIndex = b_nrows;
|
| | 121 | isColonRows = true;
|
| | 122 | if creating || (isTabularRHS && isa(b,class(t)))
|
| | 123 | % In either case, if the RHS is tabular, copy the rows dim,
|
| | 124 | % including size and labels (if any), to the LHS. For creation, the
|
| | 125 | % RHS _is_ tabular, and the LHS is assumed to be an empty tabular
|
| | 126 | % "like" the RHS. For growing a 0x0, it must be the same "kind" of
|
| | 127 | % tabular as the LHS.
|
| | 128 | t.rowDim = b.rowDim;
|
| | 129 | else
|
| | 130 | % Otherwise the RHS is a cell array (assigning into a 0x0 tabular
|
| | 131 | % using cell convenience syntax). Use default (possibly none) row
|
| | 132 | % labels for the LHS.
|
| | 133 | t.rowDim = t.rowDim.createLike(b_nrows);
|
| | 134 | end
|
| | 135 | else % t(indices,...) = b, t(logical,...) = b, or t(labels,...) = b
|
| | 136 | % Translate row labels into indices (leave logical alone).
|
| | 137 | [rowIndices,numRowIndices,maxRowIndex,isColonRows,isRowLabels,t.rowDim] = ...
|
| | 138 | t.rowDim.subs2inds(s(1).subs{1},subsType.assignment);
|
| | 139 |
|
| | 140 | % Creating using numeric or logical subscripts copies row labels from
|
| | 141 | % the RHS if the RHS is tabular and has row labels (the LHS is assumed
|
| | 142 | % to be an empty tabular "like" the RHS in the creation case). Growing
|
| | 143 | % from a 0x0 with explicit row subscripts on the LHS does not copy row
|
| | 144 | % labels.
|
| | 145 | if creating && ~isRowLabels && isTabularRHS && b.rowDim.hasLabels
|
| | 146 | % Let standard assignment behavior handle repeated LHS subs.
|
| | 147 | newLabels = b.rowDim.labels([]); newLabels(rowIndices) = b.rowDim.labels;
|
| | 148 | % The rows being created may be discontiguous, fill in default row labels.
|
| | 149 | holes = true(1,t.rowDim.length); holes(rowIndices) = false;
|
| | 150 | if any(holes)
|
| | 151 | newLabels(holes) = b.rowDim.defaultLabels(find(holes)); %#ok<FNDSB>
|
| | 152 | end
|
| | 153 | t.rowDim = t.rowDim.setLabels(newLabels);
|
| | 154 | end
|
| | 155 | end
|
| | 156 |
|
| | 157 | % Next sort out the vars subscript, and copy the RHS's var names and per-var
|
| | 158 | % metadata as appropriate
|
| | 159 | if isColon(s(1).subs{2}) % t(...,:) = b
|
| | 160 | % When creating a new tabular, or growing from 0x0, interpret a ':' vars
|
| | 161 | % subscript with respect to the RHS, not as nothing.
|
| | 162 | varIndices = 1:b_nvars;
|
| | 163 | numVarIndices = b_nvars;
|
| | 164 | isColonVars = true;
|
| | 165 | if creating || isTabularRHS
|
| | 166 | % In either case, if the RHS is tabular, copy the rows dim,
|
| | 167 | % including size, names, and ALL per-var metadata, to the LHS. For
|
| | 168 | % creation, the RHS _is_ tabular, and the LHS is assumed to be an
|
| | 169 | % empty tabular "like" the RHS. For growing a 0x0, it may or may not
|
| | 170 | % be tabular.
|
| | 171 | t.varDim = b.varDim;
|
| | 172 | else
|
| | 173 | % Otherwise the RHS is a cell array (assigning into a 0x0 tabular
|
| | 174 | % using cell convenience syntax). Use default (possibly none) var
|
| | 175 | % names for the LHS, and there's no metadata to copy.
|
| | 176 | t.varDim = t.varDim.createLike(b_nvars,t.varDim.defaultLabels(1:b_nvars));
|
| | 177 | end
|
| | 178 | else % t(...,indices) = b, t(...,logical) = b, or t(...,labels) = b
|
| | 179 | % Translate variable names or logical into indices.
|
| | 180 | [varIndices,numVarIndices,~,isColonVars,isVarNames,t.varDim] = ...
|
| | 181 | t.varDim.subs2inds(s(1).subs{2},subsType.assignment,t.data);
|
| | 182 |
|
| | 183 | % Creating using numeric or logical subscripts copies var names from the
|
| | 184 | % RHS if that is tabular. The LHS is assumed to be an empty tabular
|
| | 185 | % "like" the RHS.
|
| | 186 | if creating && ~isVarNames && isTabularRHS
|
| | 187 | % Let standard assignment behavior handle repeated LHS subs.
|
| | 188 | newLabels = {}; newLabels(varIndices) = b.varDim.labels;
|
| | 189 | t.varDim = t.varDim.setLabels(newLabels);
|
| | 190 | end
|
| | 191 | end
|
| | 192 |
|
| | 193 | % Creating a tabular will take per-array metadata and dimension metadata
|
| | 194 | % from the RHS if that is tabular.
|
| | 195 | if creating && isTabularRHS
|
| | 196 | t.arrayProps = b.arrayProps;
|
| | 197 | t.metaDim = t.metaDim.setLabels(b.metaDim.labels);
|
| | 198 | end
|
| | 199 |
|
< 0.001 | 1292 | 200 | else
|
| | 201 | % Assignment into or deletion from an existing non-degenerate table
|
< 0.001 | 1292 | 202 | if deleting
|
| | 203 | subsType = subsType.deletion;
|
< 0.001 | 1292 | 204 | else
|
0.001 | 1292 | 205 | subsType = subsType.assignment;
|
< 0.001 | 1292 | 206 | end
|
| | 207 |
|
| | 208 | % Translate row labels into indices (leave logical and ':' alone), and
|
| | 209 | % update the rowDim.
|
0.038 | 1292 | 210 | [rowIndices,numRowIndices,maxRowIndex,isColonRows,~,t.rowDim] = ...
|
| 1292 | 211 | t.rowDim.subs2inds(s(1).subs{1},subsType);
|
| | 212 | % Translate variable names, logical, or ':' into indices and update the
|
| | 213 | % varDim.
|
0.037 | 1292 | 214 | [varIndices,numVarIndices,~,isColonVars,~,t.varDim] = ...
|
| 1292 | 215 | t.varDim.subs2inds(s(1).subs{2},subsType,t.data);
|
< 0.001 | 1292 | 216 | end
|
| | 217 |
|
| | 218 | % Syntax: t(rowIndices,:) = []
|
| | 219 | % t(:,varIndices) = []
|
| | 220 | % t(:,:) = [] deletes all rows, but doesn't delete any vars
|
| | 221 | % t(rowIndices,varIndices) = [] is illegal
|
| | 222 | %
|
| | 223 | % Deletion of complete rows or entire variables.
|
< 0.001 | 1292 | 224 | if deleting
|
| | 225 | % Delete rows across all variables
|
| | 226 | if isColonVars
|
| | 227 | if isColonRows
|
| | 228 | % subs2inds saw ':' and left t.rowDim alone, thinking it was t(:,varIndices) = [].
|
| | 229 | % But it's t(:,:) = [], which should behave like t(1:n,:) = [], so remove all
|
| | 230 | % rows as if it had been that.
|
| | 231 | t.rowDim = t.rowDim.deleteFrom(rowIndices);
|
| | 232 | end
|
| | 233 |
|
| | 234 | % Numeric indices and row labels can specify repeated LHS vars (logical and : can't).
|
| | 235 | % Row labels have been translated to numeric indices, now remove any repeats.
|
| | 236 | if isnumeric(rowIndices)
|
| | 237 | rowIndices = unique(rowIndices);
|
| | 238 | numRowIndices = length(rowIndices);
|
| | 239 | end
|
| | 240 | newNrows = t_nrowsExisting - numRowIndices;
|
| | 241 | t_data = t.data; t.data = []; % DO NOT separate these calls: necessary to avoid shared copy unsharing
|
| | 242 | for j = 1:t_nvarsExisting
|
| | 243 | var_j = t_data{j}; t_data{j} = []; % DO NOT separate these calls: necessary to avoid shared copy unsharing
|
| | 244 | if isa(var_j,'tabular')
|
| | 245 | % Use dot method to force dispatch to overloaded table subscripting
|
| | 246 | var_j = move(var_j).subsasgnParens({rowIndices ':'},[],false,true);
|
| | 247 | elseif ismatrix(var_j)
|
| | 248 | var_j(rowIndices,:) = []; % without using reshape, may not be one
|
| | 249 | else
|
| | 250 | sizeOut = size(var_j); sizeOut(1) = newNrows;
|
| | 251 | var_j(rowIndices,:) = [];
|
| | 252 | var_j = reshape(var_j,sizeOut);
|
| | 253 | end
|
| | 254 | t_data{j} = var_j;
|
| | 255 | end
|
| | 256 | t.data = t_data;
|
| | 257 |
|
| | 258 | % Delete entire variables
|
| | 259 | elseif isColonRows
|
| | 260 | varIndices = unique(varIndices); % subs2inds converts all types of var subscripts to numeric
|
| | 261 | t.data(varIndices) = [];
|
| | 262 |
|
| | 263 | else
|
| | 264 | error(message('MATLAB:table:InvalidEmptyAssignment'));
|
| | 265 | end
|
| | 266 |
|
| | 267 | % Syntax: t(rowIndices,varIndices) = b
|
| | 268 | %
|
| | 269 | % Assignment from a table. This operation is supposed to replace or
|
| | 270 | % grow at the level of the _table_. So no internal reshaping of
|
| | 271 | % variables is allowed -- we strictly enforce sizes. In other words, the
|
| | 272 | % existing table has a specific size/shape for each variable, and
|
| | 273 | % assignment at this level must respect that.
|
< 0.001 | 1292 | 274 | else
|
< 0.001 | 1292 | 275 | if b_nrows*b_nvars == 1 % isscalar(b)
|
| | 276 | % Scalar expand a RHS that's single table element or cell (it may itself contain
|
| | 277 | % a non-scalar) to the size of the target LHS subarray.
|
0.157 | 785 | 278 | b = repmat(b,numRowIndices,numVarIndices);
|
0.006 | 785 | 279 | [b_nrows,b_nvars] = size(b); %#ok<ASGLU> keep these current
|
< 0.001 | 507 | 280 | else
|
| | 281 | % Tabular assignment requires equal RHS and LHS sizes even for
|
| | 282 | % empty-to-empty assignment. This is stricter than the core types, but
|
| | 283 | % their behavior for empty assignments is only there for legacy reasons.
|
| | 284 | % Per-var properties make tabular assignment more complex than numeric.
|
< 0.001 | 507 | 285 | if b_nrows ~= numRowIndices
|
| | 286 | error(message('MATLAB:table:RowDimensionMismatch'));
|
< 0.001 | 507 | 287 | elseif b_nvars ~= numVarIndices
|
| | 288 | error(message('MATLAB:table:VarDimensionMismatch'));
|
< 0.001 | 507 | 289 | end
|
< 0.001 | 1292 | 290 | end
|
| | 291 |
|
< 0.001 | 1292 | 292 | if isTabularRHS
|
< 0.001 | 1292 | 293 | b_data = b.data;
|
| | 294 | elseif iscell(b)
|
| | 295 | if ~ismatrix(b)
|
| | 296 | error(message('MATLAB:table:NDCell'));
|
| | 297 | end
|
| | 298 | b_data = tabular.container2vars(b);
|
| | 299 | else
|
| | 300 | % Raw values are not accepted as the RHS with '()' subscripting: With a
|
| | 301 | % single variable, you can use dot subscripting. With multiple variables,
|
| | 302 | % you can either wrap them up in a table, accepted above, or use braces
|
| | 303 | % if the variables are homogeneous.
|
| | 304 | error(message('MATLAB:table:InvalidRHS'));
|
< 0.001 | 1292 | 305 | end
|
| | 306 |
|
| | 307 | % varIndices might contain repeated indices into t, but existingVarLocsInB and
|
| | 308 | % newVarLocsInB (see below) always contain unique (and disjoint) indices into b.
|
| | 309 | % In that case multiple vars in b will overwrite the same var in t, last one wins.
|
< 0.001 | 1292 | 310 | existingVars = (varIndices <= t_nvarsExisting); % t's original number of vars
|
0.002 | 1292 | 311 | existingVarLocsInB = find(existingVars); % vars in b being assigned to existing vars in t
|
0.007 | 1292 | 312 | t_data = t.data; t.data = []; % DO NOT separate these calls: necessary to avoid shared copy unsharing
|
0.004 | 1292 | 313 | for j = existingVarLocsInB
|
0.005 | 2306 | 314 | var_j = t_data{varIndices(j)}; t_data{varIndices(j)} = []; % DO NOT separate these calls: necessary to avoid shared copy unsharing
|
| | 315 | % The size of the RHS has to match what it's going into.
|
< 0.001 | 2306 | 316 | try
|
0.003 | 2306 | 317 | var_b = b_data{j};
|
0.002 | 2306 | 318 | if ~ismatrix(var_b)
|
| | 319 | var_b = matricize(var_b);
|
< 0.001 | 2306 | 320 | end
|
| | 321 |
|
| | 322 | % Save attributes of var_j for error handling before attempting assignment in-place (which renders var_j inaccessible after exception)
|
0.012 | 2306 | 323 | sizeLHS = size(var_j); sizeLHS(1) = numRowIndices;
|
< 0.001 | 2306 | 324 | var_j_ischar = ischar(var_j);
|
| | 325 |
|
| | 326 | % In cases where the whole var is moved, i.e. rowIndices is ':', this is faster, but a valid
|
| | 327 | % RHS may not have same type or trailing size as the LHS var, and it's difficult to do the
|
| | 328 | % right error checking - so do it as a subscripted assignment.
|
| | 329 | % if isColonRows && isequal(sizeLHS,size(b_data{j}))) && isa(b_data{j},class(var_j))
|
| | 330 | % var_j = var_b;
|
| | 331 | % else
|
0.006 | 2306 | 332 | if isa(var_j,'tabular')
|
| | 333 | var_j = move(var_j).subsasgnParens({rowIndices ':'},var_b,creating); % % force dispatch to overloaded table subscripting
|
< 0.001 | 2306 | 334 | else
|
0.022 | 2306 | 335 | var_j(rowIndices,:) = var_b;
|
< 0.001 | 2306 | 336 | end
|
| | 337 | % end
|
| | 338 | % No need to check for size change, RHS and LHS are identical sizes.
|
0.004 | 2306 | 339 | t_data{varIndices(j)} = var_j;
|
| | 340 | catch ME
|
| | 341 | if matches(ME.identifier, ["MATLAB:invalidConversion" "MATLAB:UnableToConvert"])
|
| | 342 | if iscell(b) && var_j_ischar && iscellstr(var_b) %#ok<ISCLSTR>
|
| | 343 | % Give a specific error when tabular.container2vars has converted
|
| | 344 | % char inside a cell RHS into a cellstr.
|
| | 345 | error(message('MATLAB:table:CharAssignFromCellRHS'));
|
| | 346 | else
|
| | 347 | % Otherwise preserve the conversion error.
|
| | 348 | rethrow(ME);
|
| | 349 | end
|
| | 350 | elseif prod(sizeLHS) ~= prod(size(b_data{j})) %#ok<PSIZE> avoid numel, it may return 1
|
| | 351 | % Already checked that the height of the RHS is the same as the
|
| | 352 | % number of LHS rows being assigned into. But for each variable,
|
| | 353 | % the "internal" sizes must match.
|
| | 354 | error(message('MATLAB:table:AssignmentDimensionMismatch', t.varDim.labels{varIndices(j)}));
|
| | 355 | elseif (ME.identifier == "MATLAB:subsassigndimmismatch") ...
|
| | 356 | && var_j_ischar && isstring(var_b)
|
| | 357 | % String into Nx1 char is a special case: the string elements
|
| | 358 | % are converted to char row vectors, and may not be the correct
|
| | 359 | % strlength to assign into the LHS char. But the check against
|
| | 360 | % sizeLHS fails to catch the "inner" size mismatch because the
|
| | 361 | % RHS has the right "outer" size before conversion to char.
|
| | 362 | error(message('MATLAB:table:AssignmentDimensionMismatch', t.varDim.labels{varIndices(j)}));
|
| | 363 | else
|
| | 364 | rethrow(ME);
|
| | 365 | end
|
< 0.001 | 2306 | 366 | end
|
< 0.001 | 2306 | 367 | end
|
| | 368 |
|
| | 369 | % Add new variables if necessary. Note that b's varnames do not
|
| | 370 | % propagate to a in () assignment, unless t is being created or grown
|
| | 371 | % from 0x0. They do for horzcat, though.
|
0.002 | 1292 | 372 | newVarLocsInB = find(~existingVars); % vars in b being assigned to new vars in t
|
0.002 | 1292 | 373 | newVarLocsInT = varIndices(~existingVars); % new vars being created in t (possibly repeats)
|
< 0.001 | 1292 | 374 | if ~isempty(newVarLocsInB)
|
| | 375 | % Warn if we have to lengthen the new variables to match the height of
|
| | 376 | % the table. Don't warn about default values "filled in in the middle"
|
| | 377 | % for these new vars.
|
| | 378 | if maxRowIndex < t_nrowsExisting
|
| | 379 | warning(message('MATLAB:table:RowsAddedNewVars'));
|
| | 380 | end
|
| | 381 |
|
| | 382 | % Add cells for new vars being created, not including repeated LHS var subscripts.
|
| | 383 | numUniqueNewVarsAssignedTo = length(unique(newVarLocsInT));
|
| | 384 | t_data = [t_data cell(1,numUniqueNewVarsAssignedTo)];
|
| | 385 |
|
| | 386 | for j = newVarLocsInB
|
| | 387 | var_b = b_data{j};
|
| | 388 | if isColonRows
|
| | 389 | var_j = var_b;
|
| | 390 | else
|
| | 391 | % Start the new variable out as 0-by-(trailing size of b),
|
| | 392 | % then let the assignment add rows.
|
| | 393 | var_j = repmat(var_b,[0 ones(1,ndims(var_b)-1)]);
|
| | 394 | if isa(var_j,'tabular')
|
| | 395 | % Use dot method to force dispatch to overloaded table subscripting
|
| | 396 | var_j = move(var_j).subsasgnParens({rowIndices ':'},matricize(var_b),creating);
|
| | 397 | else
|
| | 398 | var_j(rowIndices,:) = matricize(var_b);
|
| | 399 | end
|
| | 400 | end
|
| | 401 | % A new var may need to grow to fit the table
|
| | 402 | if size(var_j,1) < t_nrowsExisting % t's original number of rows
|
| | 403 | var_j = t.lengthenVar(var_j, t_nrowsExisting);
|
| | 404 | end
|
| | 405 | t_data{varIndices(j)} = var_j;
|
| | 406 | end
|
| | 407 |
|
| | 408 | % Copy per-var properties from b to t.
|
| | 409 | if isTabularRHS
|
| | 410 | t.varDim = t.varDim.moveProps(b.varDim,newVarLocsInB,newVarLocsInT);
|
| | 411 | end
|
| | 412 | % Detect conflicts between the new var names and the existing dim names.
|
| | 413 | t.metaDim = t.metaDim.checkAgainstVarLabels(t.varDim.labels);
|
< 0.001 | 1292 | 414 | end
|
0.003 | 1292 | 415 | t.data = t_data;
|
| | 416 |
|
< 0.001 | 1292 | 417 | if (maxRowIndex > t_nrowsExisting) % t's original number of rows
|
| | 418 | % If the vars being assigned to are now taller than the table, add rows
|
| | 419 | % to the rest of the table, including row labels. This might be because
|
| | 420 | % the assignment lengthened existing vars, or because the assignment
|
| | 421 | % created new vars taller than the table. Warn only if we have to
|
| | 422 | % lengthen existing vars that have not been assigned to -- if there's
|
| | 423 | % currently only one var in the table (which might be existing or new),
|
| | 424 | % don't warn about any default values "filled in in the middle".
|
| | 425 | numUniqueExistingVarsAssignedTo = length(unique(varIndices(existingVars)));
|
| | 426 | if numUniqueExistingVarsAssignedTo < t_nvarsExisting % some existing vars were not assigned to
|
| | 427 | warning(message('MATLAB:table:RowsAddedExistingVars'));
|
| | 428 | end
|
| | 429 | t = t.lengthenTo(maxRowIndex);
|
< 0.001 | 1292 | 430 | end
|
0.008 | 1292 | 431 | end
|