gusucode.com > datatypes 工具箱matlab源码程序 > datatypes/@categorical/mergecats.m
function a = mergecats(a,oldCategories,newCategory) %MERGECATS Merge categories in a categorical array. % B = MERGECATS(A,OLDCATEGORIES,NEWCATEGORY) merges two or more % categories in the categorical array A into a single new category. % OLDCATEGORIES is a cell array of character vectors that specifies the % categories to be merged. Any elements of A whose value is a category % in OLDCATEGORIES are assigned the category NEWCATEGORY in the % corresponding elements of B. NEWCATEGORY is a character vector that % specifies the new category. % % B = MERGECATS(A,CATEGORIES) merges the categories specified by the cell % array of character vectors CATEGORIES into the first specified % category, CATEGORIES{1}. Any elements of A whose value is a category in % CATEGORIES are assigned that category. % % See also CATEGORIES, ADDCATS, REMOVECATS, ISCATEGORY, RENAMECATS, REORDERCATS, SETCATS. % Copyright 2013-2016 The MathWorks, Inc. if nargout == 0 error(message('MATLAB:categorical:NoLHS',upper(mfilename),upper(mfilename),',OLD,NEW')); end oldCategories = checkCategoryNames(oldCategories,1); % remove any duplicates isOrdinal = a.isOrdinal; % Find the codes for the categories that will be merged. Ignore anything in % oldCategories that didn't match a category in A. [~,oldCodes] = ismember(oldCategories,a.categoryNames); oldCodes(oldCodes == 0) = []; if isempty(oldCodes), return, end if nargin < 3 newCategory = oldCategories{1}; elseif ischar(newCategory) && isrow(newCategory) newCategory = strtrim(newCategory); if strcmp(categorical.undefLabel,newCategory) error(message('MATLAB:categorical:mergecats:UndefinedLabel', categorical.undefLabel)); elseif isempty(newCategory) error(message('MATLAB:categorical:mergecats:InvalidNewCategory')); end else error(message('MATLAB:categorical:mergecats:InvalidNewCategory')); end % Set up a vector to map the existing categories to the new, merged categories. acodes = a.codes; anames = a.categoryNames; convert = 1:cast(length(anames),'like',acodes); % The merged category may be an existing category, or may be a new category. newCode = find(strcmp(newCategory,anames)); % possibly empty if isempty(newCode) || any(newCode==oldCodes) % Merging old categories to either a new category, or to one in that group. The % merged category's internal code will reuse the lowest of the old codes. Name % the merged category, with what may be a new or an old name. [newCode,j] = min(oldCodes); oldCodes(j) = []; anames{newCode} = newCategory; else % Merging old categories to an existing category not in that group. Already have % the internal code, and the name is already correct. end % Cannot merge nonconsecutive ordinal categories unless they're being merged to % one in the middle. if isOrdinal && any(diff(sort([oldCodes; newCode]))~=1) error(message('MATLAB:categorical:mergecats:NonconsecutiveCategories')); end % Remove the remaining old categories from A anames(oldCodes) = []; a.categoryNames = anames; % Merge the codes for the old categories to the new category, and shift the % codes for the existing categories down. offset = zeros(size(convert),'like',acodes); offset(oldCodes) = 1; convert = convert - cumsum(offset); convert(oldCodes) = convert(newCode); convert = [categorical.undefCode convert]; % there may be undefined elements in a.codes acodes = reshape(convert(acodes+1),size(acodes)); % acodes has correct type because convert does a.codes = categorical.castCodes(acodes,length(anames)); % possibly downcast acodes