gusucode.com > datatypes 工具箱matlab源码程序 > datatypes/@table/table.m
classdef (Sealed) table < tabular %TABLE Table. % Tables are used to collect heterogeneous data and metadata into a single % container. Tables are suitable for storing column-oriented or tabular data % that are often stored as columns in a text file or in a spreadsheet. Tables % can accommodate variables of different types, sizes, units, etc. They are % often used to store experimental data, with rows representing different % observations and columns representing different measured variables. % % Use the TABLE constructor to create a table from variables in the MATLAB % workspace. Use the readtable function to create a table by reading data % from a text or spreadsheet file. % % Tables can be subscripted using parentheses much like ordinary numeric % arrays, but in addition to numeric and logical indices, you can use a % table's variable and row names as indices. You can access individual % variables in a table much like fields in a structure, using dot % subscripting. You can access the contents of one or more variables using % brace subscripting. % % Tables can contain different kinds of variables, including numeric, logical, % character, categorical, and cell. However, a table is a different class % than the variables that it contains. For example, even a table that % contains only variables that are double arrays cannot be operated on as if % it were itself a double array. However, using dot subscripting, you can % operate on a variable in a table as if it were a workspace variable. Using % brace subscripting, you can operate on one or more variables in a table as % if they were in a homogeneous array. % % A table T has properties that store metadata such as its variable and row % names. Access or assign to a property using P = T.Properties.PropName or % T.Properties.PropName = P, where PropName is one of the following: % % TABLE metadata properties: % Description - A character vector describing the table % DimensionNames - A two-element cell array of character vectors containing names of % the dimensions of the table % VariableNames - A cell array containing names of the variables in the table % VariableDescriptions - A cell array of character vectors containing descriptions of the % variables in the table % VariableUnits - A cell array of character vectors containing units for the variables % in table % RowNames - A cell array of nonempty, distinct character vectors containing names % of the rows in the table % UserData - A variable containing any additional information associated % with the table. You can assign any value to this property. % % TABLE methods and functions: % Construction and conversion: % table - Create a table from workspace variables. % array2table - Convert homogeneous array to table. % cell2table - Convert cell array to table. % struct2table - Convert structure array to table. % table2array - Convert table to a homogeneous array. % table2cell - Convert table to cell array. % table2struct - Convert table to structure array. % Import and export: % readtable - Create a table by reading from a file. % writetable - Write a table to a file. % write - Write a table to a file. % Size and shape: % istable - True for tables. % size - Size of a table. % width - Number of variables in a table. % height - Number of rows in a table. % ndims - Number of dimensions of a table. % numel - Number of elements in a table. % horzcat - Horizontal concatenation for tables. % vertcat - Vertical concatenation for tables. % Set membership: % intersect - Find rows common to two tables. % ismember - Find rows in one table that occur in another table. % setdiff - Find rows that occur in one table but not in another. % setxor - Find rows that occur in one or the other of two tables, but not both. % unique - Find unique rows in a table. % union - Find rows that occur in either of two tables. % join - Merge two tables by matching up rows using key variables. % innerjoin - Inner join between two tables. % outerjoin - Outer join between two tables. % Data organization: % summary - Print summary of a table. % sortrows - Sort rows of a table. % stack - Stack up data from multiple variables into a single variable. % unstack - Unstack data from a single variable into multiple variables. % ismissing - Find elements in a table that contain missing values. % standardizeMissing - Insert missing data indicators into a table. % Computations on tables: % varfun - Apply a function to variables in a table. % rowfun - Apply a function to rows of a table. % % Examples: % % % Create a table from individual workspace variables. % load patients % patients = table(LastName,Gender,Age,Height,Weight,Smoker,Systolic,Diastolic) % % % Select the rows for patients who smoke, and a subset of the variables. % smokers = patients(patients.Smoker == true, {'LastName' 'Gender' 'Systolic' 'Diastolic'}) % % % Convert the two blood pressure variables into a single variable. % patients.BloodPressure = [patients.Systolic patients.Diastolic]; % patients(:,{'Systolic' 'Diastolic'}) = [] % % % Pick out two specific patients by the LastName variable. % patients(ismember(patients.LastName,{'Smith' 'Jones'}), :) % % % Convert the LastName variable into row names. % patients.Properties.RowNames = patients.LastName; % patients.LastName = [] % % % Use the row names to pick out two specific patients. % patients({'Smith' 'Jones'},:) % % % Add metadata to the table. % patients.Properties.Description = 'Simulated patient data'; % patients.Properties.VariableUnits = {'' 'Yrs' 'In' 'Lbs' '' 'mm Hg'}; % patients.Properties.VariableDescriptions{6} = 'Systolic/Diastolic'; % summary(patients) % % % Create a new variable in the table from existing variables. % patients.BMI = (patients.Weight * 0.453592) ./ (patients.Height * 0.0254).^2 % patients.Properties.VariableUnits{'BMI'} = 'kg/m^2'; % patients.Properties.VariableDescriptions{'BMI'} = 'Body Mass Index'; % % % Sort the table based on the new variable. % sortrows(patients,'BMI') % % % Make a scatter plot of two of the table's variables. % plot(patients.Height,patients.Weight,'o') % % % Create tables from text and spreadsheet files % patients2 = readtable('patients.dat','ReadRowNames',true) % patients3 = readtable('patients.xls','ReadRowNames',true) % % % Create a table from a numeric matrix % load tetmesh.mat % t = array2table(X,'VariableNames',{'x' 'y' 'z'}); % plot3(t.x,t.y,t.z,'.') % % See also TABLE, CATEGORICAL % Copyright 2012-2016 The MathWorks, Inc. properties(Constant, Access='protected') % Constant properties are not persisted when serialized version = 2.0; propertyNames = [fieldnames(tabular.arrayPropsDflts); ... matlab.internal.table.tableMetaDim.propertyNames; ... matlab.internal.table.tableVarNamesDim.propertyNames; ... matlab.internal.table.tableRowNamesDim.propertyNames]; defaultDimNames = matlab.internal.table.dfltDimNames; end properties(Access='protected') % * DO NOT MODIFY THIS LIST OF NON-TRANSIENT INSTANCE PROPERTIES * % Declare any additional properties in the Transient block below, % and add proper logic in saveobj/loadobj to handle persistence data = cell(1,0); end properties(Transient, Access='protected') % Create the metaDim to not display the row labels header, and with dim names % backwards compatibility turned on metaDim = matlab.internal.table.tableMetaDim(2,table.defaultDimNames,false,true); rowDim = matlab.internal.table.tableRowNamesDim(0); varDim = matlab.internal.table.tableVarNamesDim(0); % 'Properties' will appear to contain this, as well as the per-row, per-var, % and per-dimension properties contained in rowDim, varDim. and metaDim, arrayProps = tabular.arrayPropsDflts; end methods function t = table(varargin) %TABLE Create a table from workspace variables. % T = TABLE(VAR1, VAR2, ...) creates a table T from the workspace % variables VAR1, VAR2, ... . All variables must have the same number % of rows. % % T = TABLE(..., 'VariableNames', {'name1', ..., 'name_M'}) creates a % table containing variables that have the specified variable names. % The names must be valid MATLAB identifiers, and unique. % % T = TABLE(..., 'RowNames', {'name1', ..., 'name_N'}) creates a table % that has the specified row names. The names need not be valid MATLAB % identifiers, but must be unique. % % Tables can contain variables that are built-in types, or objects that % are arrays and support standard MATLAB parenthesis indexing of the form % var(i,...), where i is a numeric or logical vector that corresponds to % rows of the variable. In addition, the array must implement a SIZE method % with a DIM argument, and a VERTCAT method. % % % Examples: % % Create a table from individual workspace variables. % load patients % patients = table(LastName,Gender,Age,Height,Weight,Smoker,Systolic,Diastolic) % patients.Properties.Description = 'Simulated patient data'; % patients.Properties.VariableUnits = {'' '' 'Yrs' 'In' 'Lbs' '' 'mm Hg' 'mm Hg'}; % % See also READTABLE, CELL2TABLE, ARRAY2TABLE, STRUCT2TABLE. if nargin == 0 % Nothing to do else % Construct from separate variables [numVars,numRows] = tabular.countVarInputs(varargin); vars = varargin(1:numVars); if numVars < nargin pnames = {'VariableNames' 'RowNames' }; dflts = { [] [] }; try [varnames,rownames,supplied] ... = matlab.internal.table.parseArgs(pnames, dflts, varargin{numVars+1:end}); catch ME % The inputs included a 1xM string that was interpreted as a param name, % but something went wrong. If all of the preceedng inputs had one row, % or if that string was first, these two errors suggest that the string % was intended as data. Suggest alternative options, in that case. if (numVars == 0 || numRows == 1) if strcmp(ME.identifier,'MATLAB:table:parseArgs:BadParamName') || ... strcmp(ME.identifier,'MATLAB:table:parseArgs:WrongNumberArgs') cause = message('MATLAB:table:ConstructingFromStrings'); ME = addCause(ME,MException(cause.Identifier,'%s',getString(cause))); end end throw(ME); end else supplied.VariableNames = false; supplied.RowNames = false; end if supplied.RowNames if numVars == 0, numRows = length(rownames); end else rownames = {}; end if ~supplied.VariableNames % Get the workspace names of the input arguments from inputname varnames = repmat({''},1,numVars); for i = 1:numVars, varnames{i} = inputname(i); end % Fill in default names for data args where inputname couldn't empties = cellfun('isempty',varnames); if any(empties) varnames(empties) = matlab.internal.table.dfltVarNames(find(empties)); %#ok<FNDSB> end % Make sure default names or names from inputname don't conflict varnames = matlab.lang.makeUniqueStrings(varnames,{},namelengthmax); end t.rowDim = matlab.internal.table.tableRowNamesDim(numRows,rownames); t.varDim = matlab.internal.table.tableVarNamesDim(numVars,varnames); % error if invalid, duplicate, or empty t.data = vars; % Detect conflicts between the var names and the default dim names. t.metaDim = t.metaDim.checkAgainstVarLabels(varnames); end end % table constructor end % methods block methods(Hidden) % hidden methods block write(t,filename,varargin) end methods(Hidden, Static) % This function is for internal use only and will change in a % future release. Do not use this function. t = readFromFile(filename,args) function t = empty(varargin) %EMPTY Create an empty table. % T = TABLE.EMPTY() creates a 0x0 table. % % T = TABLE.EMPTY(NROWS,NVARS) or T = TABLE.EMPTY([NROWS NVARS]) creates an % NROWSxNVARS table. At least one of NROWS or NVARS must be zero. % % See also TABLE, ISEMPTY. if nargin == 0 t = table(); else sizeOut = size(zeros(varargin{:})); if prod(sizeOut) ~= 0 error(message('MATLAB:table:empty:EmptyMustBeZero')); elseif length(sizeOut) > 2 error(message('MATLAB:table:empty:EmptyMustBeTwoDims')); else % Create a 0x0 table, and then resize to the correct number % of rows or variables. t = table(); if sizeOut(1) > 0 t.rowDim = t.rowDim.lengthenTo(sizeOut(1)); end if sizeOut(2) > 0 t.varDim = t.varDim.lengthenTo(sizeOut(2)); t.data = cell(1,sizeOut(2)); % assume double end end end end % Called by cell2table, struct2table function t = fromScalarStruct(s) % This function is for internal use only and will change in a % future release. Do not use this function. % Construct a table from a scalar struct vnames = fieldnames(s); p = length(vnames); if p > 0 n = unique(structfun(@(f)size(f,1),s)); if ~isscalar(n) error(message('MATLAB:table:UnequalFieldLengths')); end else n = 0; end t = table(); t.data = struct2cell(s)'; t.rowDim = matlab.internal.table.tableRowNamesDim(n); t.varDim = matlab.internal.table.tableVarNamesDim(p,vnames); end end % hidden static methods block methods(Access = 'protected') function b = cloneAsEmpty(a) %CLONEASEMPTY Create a new empty table from an existing one. % if strcmp(class(a),'table') %#ok<STISA> b = table(); % else % b is a subclass of table % b = a; % respect the subclass % % leave b.metaDim alone % b.rowDim = matlab.internal.table.tableRowNamesDim(); % b.varDim = matlab.internal.table.tableVarNamesDim(); % b.data = cell(1,0); % leave b.arrayProps alone % end end function errID = throwSubclassSpecificError(obj,msgid,varargin) % Throw the table version of the msgid error, using varargin as the % variables to fill the holes in the message. errID = throwSubclassSpecificError@tabular(obj,['table:' msgid],varargin{:}); if nargout == 0 throwAsCaller(errID); end end end methods(Access = 'protected', Static) t = readTextFile(file,args) t = readXLSFile(xlsfile,args) end %%%%% PERSISTENCE BLOCK ensures correct save/load across releases %%%%% %%%%% Properties and methods in this block maintain the exact class %%% %%%%% schema required for TABLE to persist through MATLAB releases %%%% properties(Access='private') % ** DO NOT EDIT THIS LIST OR USE THESE PROPERTIES INSIDE TABLE ** % These properties mirror the pre-R2016b internal representation, which was also % the external representation saved to mat files. Post-R2016b saveobj and loadobj % continue to use them as the external representation for save/load compatibility % with earlier releases. ndims; nrows; rownames; nvars; varnames; props; end methods(Hidden) function tsave = saveobj(t) % this saveobj is designed for 2D table only assert(t.metaDim.length==2); tsave = t; % The .data property is not transient, it will always be be saved. The other % (metadata) properties are transient, their values are saved by copying to % the corresponding (non-transient) properties of the external representation. tsave.ndims = t.metaDim.length; tsave.nrows = t.rowDim.length; tsave.nvars = t.varDim.length; tsave.rownames = t.rowDim.labels; tsave.varnames = t.varDim.labels; % .props is a scalar struct to contain any remaining metadata. At load time, % table ignores any field it does not recognize. tsave.props.Description = t.arrayProps.Description; tsave.props.UserData = t.arrayProps.UserData; tsave.props.VariableDescriptions = t.varDim.descrs; tsave.props.VariableUnits = t.varDim.units; tsave.props.DimensionNames = t.metaDim.labels; tsave.props = orderfields(tsave.props,... % guarantee the field order {'Description',... 'UserData', ... 'VariableDescriptions', ... 'VariableUnits', ... 'DimensionNames'}); % Additional data that needs to be persisted shall be packaged % and attached to tsave.props as one of its fields, such as: % % tsave.props.serializedObj % % Also add corresponding deserialization logic in loadobj below tsave.props.VersionSavedFrom = t.version; end end methods(Hidden, Static) function t = loadobj(s) noRowLabelsHeaderDisp = false; backCompatForDimNames = true; % s might be a table, or it might be a scalar struct. In either case, copy its % data into an empty table, then copy its metadata from the external % representation into the current class schema. t = table(); t.data = s.data; % Pre-R2016b tables (i.e. no 'VersionSavedFrom' field) might have DimensionNames % that do not satisfy current requirements to support new dot subscripting % functionality added in R2016b. To allow loading such existing tables, modify % any invalid names and warn. See tableMetaDim class for details. This is only % an issue for tables saved pre-2016b, newer versions with out-of-model % DimensionNames could not have been created to begin with. Even for pre-2016b, % the defaults met those requirements so the names would have had to have been % set explicitly. dimNames = s.props.DimensionNames; s.props = rmfield(s.props,'DimensionNames'); if ~isfield(s.props,'VersionSavedFrom') % pre-R2016b tables if strcmp(dimNames(2),'Variable') % If the second dim name is the old default, assume it has never been changed, % probably never even looked at, and update it to the current default to make it % consistent with the new design. Otherwise, leave it alone. dimNames(2) = t.defaultDimNames(2); end t.metaDim = matlab.internal.table.tableMetaDim(2,dimNames,noRowLabelsHeaderDisp,backCompatForDimNames); t.metaDim = t.metaDim.checkAgainstVarLabels(s.varnames); else % R2016b-on tables or timetables t.metaDim = matlab.internal.table.tableMetaDim(s.ndims,dimNames,noRowLabelsHeaderDisp,backCompatForDimNames); end t.varDim = matlab.internal.table.tableVarNamesDim(s.nvars, s.varnames); % Pre-R2016b, a 0x0 cell for rownames implicitly indicated no row names, while a 0x1 % indicated a 0xN table _with_ row names. R2016b-on use rowDim.hasLabels explicitly, % which gets set correctly here as false and true, respectively, in those two cases. t.rowDim = matlab.internal.table.tableRowNamesDim(s.nrows, s.rownames); % Remove any fields in .props that are not recognized in the current version. toRemove = setdiff(fieldnames(s.props),t.propertyNames); if ~isempty(toRemove) s.props = rmfield(s.props,toRemove); end % Restore the remaining metadata properties. t = t.setProperties(s.props); end end %%%%%%%%%%%%%%%%%%%%%%%% END PERSISTENCE BLOCK %%%%%%%%%%%%%%%%%%%%%%%% end % classdef