gusucode.com > datatypes 工具箱matlab源码程序 > datatypes/@tabular/variableEditorPaste.m
function out = variableEditorPaste(this,rows,columns,data) % This function is for internal use only and will change in a % future release. Do not use this function. % Performs a paste operation on data from the clipboard which was not % obtained from another table. % Copyright 2011-2016 The MathWorks, Inc. import matlab.internal.datatypes.istabular if istabular(data) [nrows,ncols] = variableEditorGridSize(data); else ncols = size(data,2); nrows = size(data,1); end [varNames,varIndices,classes] = variableEditorColumnNames(this); if isdatetime(this.rowDim.labels) || isduration(this.rowDim.labels) % varNames, varIndices and classes includes the rownames, if they are % datetimes or duration. This isn't needed for the paste function. varNames(1) = []; varIndices(1) = []; varIndices = varIndices-1; classes(1) = []; % col also includes the time column, so decrement it columns = columns-1; end if length(columns) == 1 && columns(1) == 0 && ... (~istabular(data) || (~isdatetime(data.rowDim.labels) && ... ~isduration(data.rowDim.labels))) % If the user has only selected the time column (0), and they are % pasting data which is not a table (hopefull it is a datetime or % the row names as durations or datetimes. (If multiple columns are % selected, or if the table contains row names, then this will be % handled as a standard paste below). if isa(data,'table') % This will work if it is a table containing datetimes or % durations data = table2array(data); end % Pasting into the row labels only if (isduration(this.rowDim.labels) && isduration(data)) || ... (isdatetime(this.rowDim.labels) && isdatetime(data)) % If the number of pasted rows does not match the number of selected rows, % just paste rows starting at the top-most row if length(rows)~=nrows && nrows>1 rows = rows(1):rows(end)+nrows-1; end if length(rows) > nrows && nrows == 1 % resize the data data = repmat(data, length(rows), 1); end this.rowDim = this.rowDim.setLabels(data, rows, true); out = this; return end end isCatClass = cellfun(@(x)isa(x,'categorical'),this.data); tableSize = size(this); % Find the table indices which correspond to the columnIntervals. If the % number of pasted columns does not match the number of selected columns, % just paste columns starting at the left-most column if length(columns)~=ncols && ncols > 1 I = unique(find(varIndices(1:end-1)>=columns(1) & varIndices(1:end-1)<=columns(end)+ncols-1)); columns = columns(1):columns(end)+ncols-1; else % Find the indices of each column colIndices=zeros(varIndices(end),1); colIndices(varIndices)=1; colIndices = cumsum(colIndices); colIndices = colIndices(1:end-1); % Index into it to convert (ignoring columns beyond the last table % column) I = unique(colIndices(columns(columns<=varIndices(end-1)))); end % If the number of pasted rows does not match the number of selected rows, % just paste rows starting at the top-most row if length(rows)~=nrows && nrows > 1 rows = rows(1):rows(end)+nrows-1; end % Paste data one variable at a time, converting from a cell array for % non-cell table variables % Paste data onto existing table variables col = 1; if ~isempty(I) % Loop through variable indices from min(I) to max(I) for k=1:length(I) if istabular(data) if width(data) == 1 % Allow pasting of a single cell selection into multiple % cells s = struct('type', {'()'}, 'subs', {{':', 1}}); else s = struct('type', {'()'}, 'subs', {{':', k}}); end variableData = subsref(data,s);%data(:,k); % this(rows,I(k)) = variableData s = struct('type',{'()'},'subs',{{rows,I(k)}}); this = subsasgn(this,s,variableData); else variableData = data(:,col:min(size(data,2),col+varIndices(I(k)+1)-varIndices(I(k))-1)); if isempty(variableData) && isscalar(data) variableData = data; end col = col+varIndices(I(k)+1)-varIndices(I(k)); % this.VarName(rows,1:size(variableData,2)) = variableData s = struct('type',{'.','()'},'subs',{varNames{I(k)},{rows,1:size(variableData,2)}}); if strcmp(classes{I(k)},'cell') this = subsasgn(this,s,variableData); elseif isCatClass(I(k)) % categorical or its subclasses % This supports assignment from a categorical or a cellstr. % Assignment of a categorical will fail if categories don't % match and the target is ordinal or protected. this = subsasgn(this,s,variableData); else try this = subsasgn(this,s,cell2mat(variableData)); catch %#ok<CTCH> this = subsasgn(this,s,variableData); end end end end end if istabular(data) && data.rowDim.hasLabels if this.rowDim.hasLabels extendRows = (rows > tableSize(1)); % rows in the source that will be new rows in the destination if any(extendRows) % Preserve the destination's row labels, but paste labels from the source for rows % that extend the destination, fixing any that duplicate existing labels. this.rowDim = this.rowDim.setLabels(data.rowDim.labels(extendRows),rows(extendRows),true); elseif isdatetime(this.rowDim.labels) || isduration(this.rowDim.labels) this.rowDim = this.rowDim.setLabels(data.rowDim.labels, rows, true); end else % Copy row labels from the source, creating default labels for the remaining rows. rowLabels = this.rowDim.emptyLabels(this.rowDim.length); rowLabels(rows) = data.rowDim.labels; this.rowDim = this.rowDim.setLabels(rowLabels,[],true,true); % fills in empty labels end end % Any remaining pasted data should be added in the columns to the right of % the table. Discontiguous column selection in this region must be % ignored since the table does not allow empty variables. appendedColumnCount = sum(columns>=varIndices(end)); if appendedColumnCount>0 %appendedCols = startColumn+ncols-varIndices(end); % Sub-reference the pasted data to get the part to be pasted after the % table. if istabular(data) [~,srcVarIndices] = variableEditorColumnNames(data); firstAppendedColumnPosition = ncols-appendedColumnCount+1; srcStartIndex = find(srcVarIndices(1:end-1)<=firstAppendedColumnPosition,1,'last'); appendedIndices = size(data,2)-srcStartIndex+1; s = struct('type',{'()'},'subs',{{':',size(data,2)-appendedIndices+1:size(data,2)}}); data = subsref(data,s); else appendedIndices = appendedColumnCount; data = data(:,end-appendedColumnCount+1:end); end lastVariableIndex = length(varIndices)-1; for index=size(data,2)-appendedIndices+1:size(data,2) % variableData = data(:,index); s = struct('type',{'()'},'subs',{{':',index}}); variableData = subsref(data,s); % this(rows,lastVariableIndex+index) = variableData s = struct('type','()','subs',{{rows,lastVariableIndex+index}}); if istabular(data) this = subsasgn(this,s,variableData); %this.Properties.VariableNames{end} = newVarName; newVarName = localGetUniqueVarName(data.varDim.labels{index},this.varDim.labels); this.varDim = this.varDim.setLabels(newVarName,size(this,2)); else try % Prevent char arrays if all(cellfun(@(x) isnumeric(x),variableData)) this = subsasgn(this,s,table(cell2mat(variableData))); else this = subsasgn(this,s,table(variableData)); end catch %#ok<CTCH> this = subsasgn(this,s,table(variableData)); end end end end out = this; function varName = localGetUniqueVarName(newVarName,varNames) % Append digits to guarantee a unique variable name ind = 1; varName = newVarName; while any(strcmp(varName,varNames)) varName = [newVarName,num2str(ind)]; ind=ind+1; end