c@0
|
1 classdef MASSEFresults < handle
|
c@0
|
2 %MASSEFRESULTS A class for storing MASSEF results
|
c@0
|
3 %
|
c@0
|
4 % The multichannel audio source separation evaluation framework uses this
|
c@0
|
5 % class to store results. You can use its methods to recall and filter
|
c@0
|
6 % the data.
|
c@0
|
7 %
|
c@0
|
8 % MASSEFRESULTS properties:
|
c@0
|
9 % Read-only properties:
|
c@0
|
10 % data - The full results set returned as a Table object
|
c@0
|
11 % (read only). The Table has the following columns:
|
c@0
|
12 % - algorithmNum - the algorithm number;
|
c@0
|
13 % - channel - the audio channel
|
c@0
|
14 % - estimateNum - the estimate number;
|
c@0
|
15 % - estTag - a tag for each estimate from a
|
c@0
|
16 % given algorithm;
|
c@0
|
17 % - metric - the performance metric;
|
c@0
|
18 % - mixNum - the mixture number; and
|
c@0
|
19 % - value - the value of the performance metric
|
c@0
|
20 % Additional mixture and algorithm information is
|
c@0
|
21 % also returned in the results set.
|
c@0
|
22 % estTags - A list of the estTags, taken from the separators,
|
c@0
|
23 % that feature in the results set (read only).
|
c@0
|
24 % metrics - The metrics that feature in the results set (read
|
c@0
|
25 % only).
|
c@0
|
26 % numAlgorithms - The number of algorithms in the results set (read
|
c@0
|
27 % only).
|
c@0
|
28 % numMixtures - The number of mixtures in the results set (read
|
c@0
|
29 % only).
|
c@0
|
30 % numEstimates - The (maximum) number of estimates in the results
|
c@0
|
31 % set (read only).
|
c@0
|
32 % numChannels - The (maximum) number of channels in the results
|
c@0
|
33 % set (read only).
|
c@0
|
34 %
|
c@0
|
35 % MASSEFRESULTS methods:
|
c@0
|
36 % MASSEFresults - Create a MASSEFresults object.
|
c@0
|
37 % algorithmInfo - Add algorithm information.
|
c@27
|
38 % boxPlot - Analyse the results data by plotting notched
|
c@27
|
39 % box plots.
|
c@0
|
40 % filter - Filter the results set.
|
c@0
|
41 % input - Add performance data.
|
c@0
|
42 % merge - Combine results array into singular object.
|
c@0
|
43 % mixtureInfo - Add mixture information.
|
c@0
|
44 % removeDuplicates - Remove duplicate data from the results
|
c@0
|
45 % object.
|
c@0
|
46 %
|
c@0
|
47 % See also MASSEFFW.
|
c@0
|
48
|
c@0
|
49 % Copyright 2016 University of Surrey.
|
c@0
|
50
|
c@0
|
51 properties (SetAccess = private, Dependent)
|
c@0
|
52 data % The full results set.
|
c@0
|
53 estTags % A tag assigned to each estimate.
|
c@0
|
54 metrics % The metrics that feature in the results set.
|
c@0
|
55 numAlgorithms % The number of algorithms in the results set.
|
c@0
|
56 numMixtures % The number of mixtures in the results set.
|
c@0
|
57 numEstimates % The (maximum) number of estimates in the results set.
|
c@0
|
58 numChannels % The (maximum) number of channels in the results set.
|
c@0
|
59 end
|
c@0
|
60
|
c@0
|
61 properties (Access = private)
|
c@0
|
62 mixtures % mixtures table
|
c@0
|
63 algorithms % algorithms table
|
c@0
|
64 performance % main performance table
|
c@0
|
65 end
|
c@0
|
66
|
c@0
|
67 methods
|
c@0
|
68
|
c@0
|
69 function obj = MASSEFresults()
|
c@0
|
70 %MASSEFRESULTS Create the results set.
|
c@0
|
71 %
|
c@0
|
72 % R = MASSEFRESULTS creates an empty MASSEFRESULTS object. Use the
|
c@0
|
73 % MASSEFRESULTS.INPUT method to add data.
|
c@0
|
74
|
c@0
|
75 obj.mixtures = cell2table(cell(0,9), 'VariableNames',{'mixNum','azi_sep','elevation','filename_t','filename_i','sofa_path','target_azi','target_ele','tir'});
|
c@0
|
76 obj.algorithms = cell2table(cell(0,2), 'VariableNames',{'algorithmNum','algorithmLabel'});
|
c@0
|
77 obj.performance = cell2table(cell(0,7), 'VariableNames',{'mixNum','algorithmNum','estimateNum','channel','metric','estTag','value'});
|
c@0
|
78
|
c@0
|
79 end
|
c@0
|
80
|
c@0
|
81 function data = get.data(obj)
|
c@0
|
82 % GET.DATA get data set
|
c@0
|
83
|
c@0
|
84 data = obj.joinLookupTables(obj.performance);
|
c@0
|
85
|
c@0
|
86 end
|
c@0
|
87
|
c@0
|
88 function metrics = get.metrics(obj)
|
c@0
|
89 % GET.METRICS get metrics
|
c@0
|
90 metrics = unique(obj.performance.metric);
|
c@0
|
91 end
|
c@0
|
92
|
c@0
|
93 function estTags = get.estTags(obj)
|
c@0
|
94 % GET.METRICS get metrics
|
c@0
|
95 estTags = unique(obj.performance.estTag);
|
c@0
|
96 end
|
c@0
|
97
|
c@0
|
98 function numAlgorithms = get.numAlgorithms(obj)
|
c@0
|
99 % GET.NUMALGORITHMS get number of algorithms
|
c@0
|
100 numAlgorithms = length(unique(obj.performance.algorithmNum));
|
c@0
|
101 end
|
c@0
|
102
|
c@0
|
103 function numMixtures = get.numMixtures(obj)
|
c@0
|
104 % GET.NUMMIXTURES get number of mixtures
|
c@0
|
105 numMixtures = length(unique(obj.performance.mixNum));
|
c@0
|
106 end
|
c@0
|
107
|
c@0
|
108 function numEstimates = get.numEstimates(obj)
|
c@0
|
109 % GET.NUMESTIMATES get number of estimates
|
c@0
|
110 numEstimates = length(unique(obj.performance.estimateNum));
|
c@0
|
111 end
|
c@0
|
112
|
c@0
|
113 function numChannels = get.numChannels(obj)
|
c@0
|
114 % GET.NUMCHANNEL get number of channels
|
c@0
|
115 numChannels = length(unique(obj.performance.channel));
|
c@0
|
116 end
|
c@0
|
117
|
c@0
|
118 function newObj = merge(obj)
|
c@0
|
119 % MERGE Combine MASSEFresults array into singular object
|
c@0
|
120 %
|
c@0
|
121 % NEWOBJ = R.MERGE() combines the elements of the MASSEFRESULTS array
|
c@0
|
122 % R into a singular MASSEFRESULTS object NEWOBJ.
|
c@0
|
123
|
c@0
|
124 newObj = obj(1);
|
c@0
|
125 if length(obj) > 1
|
c@0
|
126 for n = 2:length(obj)
|
c@0
|
127 % combine lookup table and eliminate duplicate rows
|
c@0
|
128 newObj.mixtures = vertcat(newObj.mixtures,obj(n).mixtures);
|
c@0
|
129 newObj.algorithms = vertcat(newObj.algorithms,obj(n).algorithms);
|
c@0
|
130 % combine all rows of performance tables
|
c@0
|
131 newObj.performance = vertcat(newObj.performance,obj(n).performance);
|
c@0
|
132 end
|
c@0
|
133 end
|
c@0
|
134 newObj.removeDuplicates();
|
c@0
|
135
|
c@0
|
136 end
|
c@0
|
137
|
c@0
|
138 function removeDuplicates(obj)
|
c@0
|
139 % REMOVEDUPLICATES Remove duplicate data from MASSEFresults object
|
c@0
|
140 %
|
c@0
|
141 % R.REMOVEDUPLICATES() removes duplicate results from the
|
c@0
|
142 % MASSEFRESULTS object R.
|
c@0
|
143
|
c@0
|
144 obj.mixtures = unique(obj.mixtures);
|
c@0
|
145 obj.algorithms = unique(obj.algorithms);
|
c@0
|
146 obj.performance = unique(obj.performance);
|
c@0
|
147
|
c@0
|
148 end
|
c@0
|
149
|
c@0
|
150 function data = filter(obj,varargin)
|
c@0
|
151 %FILTER Filter the results data set
|
c@0
|
152 %
|
c@0
|
153 % R.FILTER(NAME,VALUE) filters the results set contained in the
|
c@0
|
154 % MASSEFRESULTS object R using the variable names and values
|
c@0
|
155 % contained in the NAME / VALUE pair arguments. The parameters
|
c@0
|
156 % are:
|
c@0
|
157 %
|
c@0
|
158 % - 'algorithmnum' - Filters the data according to the
|
c@0
|
159 % algorithm number. The parameter should be a function
|
c@0
|
160 % handle that takes the mixture number as its input, and
|
c@0
|
161 % returns a logical value.
|
c@0
|
162 % - 'channel' - Filters the data according to channel
|
c@0
|
163 % information. The parameter can be a function handle that
|
c@0
|
164 % takes the channel number as its input, and returns a
|
c@0
|
165 % logical value. Alternatively, the parameter can be 'max'
|
c@0
|
166 % or 'mean', which calculates the the maximum or mean
|
c@0
|
167 % respectively for every combination of the other
|
c@0
|
168 % variables.
|
c@0
|
169 % - 'estimate' - Filters the data according to estimate
|
c@0
|
170 % information. The specification is identical to 'channel'.
|
c@0
|
171 % - 'estTag' - Filters the data according to the estmate tag.
|
c@0
|
172 % The parameter should be a function handle that takes the
|
c@0
|
173 % tag string as its input, and returns a logical value.
|
c@0
|
174 % - 'metric' - Filters the data according to the metric. The
|
c@0
|
175 % parameter should be a function handle that takes the
|
c@0
|
176 % metric name as its input, and returns a logical value.
|
c@0
|
177 % - 'mixnum' - Filters the data according to the mixture
|
c@0
|
178 % number. The parameter should be a function handle that
|
c@0
|
179 % takes the mixture number as its input, and returns a
|
c@0
|
180 % logical value.
|
c@0
|
181 % - 'value' - Filters the data according to the value. The
|
c@0
|
182 % parameter should be a function handle that takes the
|
c@0
|
183 % value as its input, and returns a logical value.
|
c@33
|
184 %
|
c@33
|
185 % If using the 'mean' or 'max' option, the respective variable is
|
c@33
|
186 % removed from the output.
|
c@0
|
187
|
c@23
|
188 assert(mod(length(varargin),2)==0,'MASSEFresults:filter:invalidArgs','input must contain parameter/value pairs')
|
c@0
|
189 data = obj.data;
|
c@0
|
190
|
c@0
|
191 % work through varargin
|
c@0
|
192 for n = 1:2:length(varargin)
|
c@0
|
193 filtername = varargin{n}; % column to filter on
|
c@0
|
194 filterval = varargin{n+1}; % value used to filter
|
c@0
|
195 switch lower(filtername) % do filtering
|
c@0
|
196 case 'channel'
|
c@0
|
197 data = obj.filterRowOrAggregate(data,filterval,'channel',...
|
c@0
|
198 {'mixNum','algorithmNum','estimateNum','metric'},...
|
c@0
|
199 {'mixNum','algorithmNum','metric'});
|
c@0
|
200 case 'estimate'
|
c@0
|
201 data = obj.filterRowOrAggregate(data,filterval,'estimateNum',...
|
c@0
|
202 {'mixNum','algorithmNum','channel','metric'},...
|
c@0
|
203 {'mixNum','algorithmNum','metric'});
|
c@0
|
204 case 'mixnum'
|
c@0
|
205 data = obj.filterRows(data,filterval,'mixNum');
|
c@0
|
206 case 'algorithmnum'
|
c@0
|
207 data = obj.filterRows(data,filterval,'algorithmNum');
|
c@0
|
208 case 'metric'
|
c@0
|
209 data = obj.filterRows(data,filterval,'metric');
|
c@0
|
210 case 'esttag'
|
c@0
|
211 data = obj.filterRows(data,filterval,'estTag');
|
c@0
|
212 case 'value'
|
c@0
|
213 data = obj.filterRows(data,filterval,'value');
|
c@0
|
214 otherwise
|
c@0
|
215
|
c@0
|
216 end
|
c@0
|
217
|
c@0
|
218 end
|
c@0
|
219
|
c@0
|
220 end
|
c@0
|
221
|
c@0
|
222 function mixtureInfo(obj,mixtureNumber,varargin)
|
c@0
|
223 %MIXTUREINFO Add mixture information.
|
c@0
|
224 %
|
c@0
|
225 % R.MIXTUREINFO(MIXTURENUM,NAME,VALUE) adds algorithm information
|
c@0
|
226 % for the mixture with number MIXTURENUM to the results set
|
c@0
|
227 % contained in the MASSEFRESULTS object R using the variable names
|
c@0
|
228 % and values contained in the NAME / VALUE pair arguments. The
|
c@0
|
229 % following information can be stored about each mixture:
|
c@0
|
230 %
|
c@0
|
231 % - 'azi_sep' - azimuthal separation of widest sources
|
c@0
|
232 % (numeric);
|
c@0
|
233 % - 'elevation' - median elevation of sources (numeric);
|
c@0
|
234 % - 'filename_t' - target filename (char array);
|
c@0
|
235 % - 'filename_i' - interferer filename (char array);
|
c@0
|
236 % - 'sofa_path' - SOFA filename (char array);
|
c@0
|
237 % - 'target_azi' - the target azimuth (numeric);
|
c@0
|
238 % - 'target_ele' - the target elevation (numeric); and
|
c@0
|
239 % - 'tir' - target-to-interferer ratio (dB) (numeric).
|
c@0
|
240
|
c@0
|
241 % ensure some inputs are strings
|
c@0
|
242 varargin = obj.ensureKeyValParamStrs({'sofa_path','filename_t','filename_i'},varargin);
|
c@0
|
243
|
c@0
|
244 % add data
|
c@0
|
245 obj.mixtures = obj.addData(obj.mixtures,'mixNum',mixtureNumber,varargin{:});
|
c@0
|
246
|
c@0
|
247 end
|
c@0
|
248
|
c@0
|
249 function algorithmInfo(obj,algorithmNumber,varargin)
|
c@0
|
250 %ALGORITHMINFO Add algorithm information.
|
c@0
|
251 %
|
c@0
|
252 % R.ALGORITHMINFO(ALGORITHMNUM,NAME,VALUE)| adds algorithm
|
c@0
|
253 % information for the algorithm with number ALGORITHMNUM to the
|
c@0
|
254 % results set contained in the MASSEFRESULTS object R using the
|
c@0
|
255 % variable names and values contained in the NAME / VALUE pair
|
c@0
|
256 % arguments. The following information can be stored about each
|
c@0
|
257 % algorithm:
|
c@0
|
258 %
|
c@0
|
259 % - 'algorithmLabel' - a label for the algorithm (char
|
c@0
|
260 % array).
|
c@0
|
261
|
c@0
|
262 % ensure some inputs are strings
|
c@0
|
263 varargin = obj.ensureKeyValParamStrs('algorithmLabel',varargin);
|
c@0
|
264
|
c@0
|
265 obj.algorithms = obj.addData(obj.algorithms,'algorithmNum',algorithmNumber,varargin{:});
|
c@0
|
266
|
c@0
|
267 end
|
c@0
|
268
|
c@0
|
269 function input(obj,mixtureNum,algorithmNum,estimateNum,metric,channel,estTag,value)
|
c@0
|
270 %INPUT Input performance data.
|
c@0
|
271 %
|
c@0
|
272 % R.INPUT(MIXTURENUM,ALGORITHMNUM,...
|
c@0
|
273 % ESTIMATENUM,METRIC,CHANNEL,ESTTAG,VALUE)
|
c@0
|
274 % inputs the performance data for mixture number MIXTURENUM,
|
c@0
|
275 % algorithm number ALGORITHMNUM, estimate number ESTIMATENUM,
|
c@0
|
276 % metric METRIC, channel number CHANNEL, estimate tag ESTTAG, and
|
c@0
|
277 % value VALUE to the MASSEFRESULTS instance R.
|
c@0
|
278
|
c@0
|
279 if ~ischar(estTag)
|
c@0
|
280 estTag = char(estTag);
|
c@0
|
281 end
|
c@0
|
282
|
c@0
|
283 rownames = {'mixNum','algorithmNum','estimateNum','metric','channel','estTag','value'};
|
c@0
|
284 values = {mixtureNum,algorithmNum,estimateNum,metric,channel,estTag,value};
|
c@0
|
285 row = cell2table(values, 'VariableNames',rownames);
|
c@0
|
286
|
c@0
|
287 try
|
c@0
|
288 % find existing row
|
c@0
|
289 match = obj.performance.mixNum==mixtureNum && ...
|
c@0
|
290 obj.performance.algorithmNum==algorithmNum && ...
|
c@0
|
291 obj.performance.estimateNum==estimateNum && ...
|
c@0
|
292 strcmp(metric,obj.performance.metric) && ...
|
c@0
|
293 obj.performance.channel==channel && ...
|
c@0
|
294 strcmp(estTag,obj.performance.estTag);
|
c@0
|
295
|
c@0
|
296 if any(match)
|
c@0
|
297 % replace
|
c@0
|
298 obj.performance(find(match,1,'first'),:) = row;
|
c@0
|
299 else
|
c@0
|
300 % append
|
c@0
|
301 obj.performance = [obj.performance; row];
|
c@0
|
302 end
|
c@0
|
303 catch % there is no data
|
c@0
|
304 % append
|
c@0
|
305 obj.performance = [obj.performance; row];
|
c@0
|
306 end
|
c@0
|
307
|
c@0
|
308 end
|
c@0
|
309
|
c@27
|
310 function bph = boxPlot(obj)
|
c@27
|
311 %BOXPLOT Analyse the results data by plotting notched box plots
|
c@27
|
312 %
|
c@27
|
313 % R.BOXPLOT() produces a series of box plots, one for each
|
c@27
|
314 % metric, plotting the performance of each algorithms/estimate
|
c@27
|
315 % aggregated across all mixtures.
|
c@27
|
316 %
|
c@27
|
317 % BPH = R.BOXPLOT() returns an array of IOSR.STATISTICS.BOXPLOT
|
c@27
|
318 % objects BPH for the plots.
|
c@27
|
319
|
c@27
|
320 for m = numel(obj.metrics):-1:1
|
c@27
|
321
|
c@27
|
322 tabData = obj.filter('metric', @(x) strcmp(x, obj.metrics{m}), 'channel', 'max');
|
c@27
|
323 tabData.name = strcat(tabData.algorithmLabel, ':', {' '}, tabData.estTag);
|
c@27
|
324
|
c@27
|
325 [y, x] = iosr.statistics.tab2box(tabData.name, tabData.value);
|
c@27
|
326
|
c@27
|
327 figure
|
c@27
|
328 bph(m) = iosr.statistics.boxPlot(x, y, 'notch', true);
|
c@27
|
329 ylabel(obj.metrics{m})
|
c@27
|
330 xlabel('Algorithm')
|
c@27
|
331 box on
|
c@27
|
332
|
c@27
|
333 end
|
c@27
|
334
|
c@27
|
335 end
|
c@27
|
336
|
c@0
|
337 end % public methods
|
c@0
|
338
|
c@0
|
339 methods (Hidden)
|
c@0
|
340
|
c@0
|
341 function debug(obj) %#ok<MANU>
|
c@0
|
342 keyboard;
|
c@0
|
343 end
|
c@0
|
344
|
c@0
|
345 end % hidden methods
|
c@0
|
346
|
c@0
|
347 methods (Access = private)
|
c@0
|
348
|
c@0
|
349 function dataTable = filterRowOrAggregate(obj,dataTable,filterval,col,group,altgroup)
|
c@0
|
350 %FILTERROWORAGGREGATE filter data based on aggregate function.
|
c@0
|
351
|
c@0
|
352 if ischar(filterval)
|
c@0
|
353 % special aggregate function
|
c@0
|
354 switch lower(filterval)
|
c@0
|
355 case 'max'
|
c@0
|
356 fhandle = @max;
|
c@0
|
357 case 'mean'
|
c@0
|
358 fhandle = @mean;
|
c@0
|
359 otherwise
|
c@23
|
360 error('MASSEFresults:filterRowOrAggregate:unknownOption','Unknown filter parameter ''%s''.',filterval)
|
c@0
|
361 end
|
c@0
|
362 % do stats
|
c@0
|
363 try
|
c@27
|
364 filteredTable = varfun(fhandle,dataTable,'InputVariables','value',...
|
c@0
|
365 'GroupingVariables',group);
|
c@31
|
366 keys = group;
|
c@0
|
367 catch
|
c@27
|
368 filteredTable = varfun(fhandle,dataTable,'InputVariables','value',...
|
c@0
|
369 'GroupingVariables',altgroup);
|
c@31
|
370 keys = altgroup;
|
c@0
|
371 end
|
c@0
|
372 % rename value column and delete GroupCount column
|
c@27
|
373 filteredTable = obj.findRenameVar(filteredTable,'value','value');
|
c@27
|
374 filteredTable.GroupCount = [];
|
c@31
|
375 [~, ia, ib] = intersect(filteredTable(:,keys), dataTable(:,keys));
|
c@31
|
376 dataTable.value(ib) = filteredTable.value(ia);
|
c@31
|
377 dataTable = dataTable(ib, :);
|
c@33
|
378 dataTable(:, col) = [];
|
c@0
|
379 else
|
c@0
|
380 % normal filter function
|
c@0
|
381 dataTable = obj.filterRows(dataTable,filterval,col);
|
c@0
|
382 end
|
c@0
|
383
|
c@0
|
384 end
|
c@0
|
385
|
c@0
|
386 function dataTable = joinLookupTables(obj,dataTable)
|
c@0
|
387 %JOINLOOKUPTABLES join a table to the lookup tables
|
c@0
|
388
|
c@0
|
389 if ~isempty(obj.mixtures)
|
c@0
|
390 dataTable = outerjoin(dataTable,obj.mixtures,'Type','left','MergeKeys',true,'keys','mixNum');
|
c@0
|
391 end
|
c@0
|
392 if ~isempty(obj.algorithms)
|
c@0
|
393 dataTable = outerjoin(dataTable,obj.algorithms,'Type','left','MergeKeys',true);
|
c@0
|
394 end
|
c@0
|
395
|
c@0
|
396 end
|
c@0
|
397
|
c@0
|
398 end % private methods
|
c@0
|
399
|
c@0
|
400 methods (Static, Access = private)
|
c@0
|
401
|
c@0
|
402 function dataTable = addData(dataTable,key,keyVal,varargin)
|
c@0
|
403 %ADDDATA add data to lookup tables.
|
c@0
|
404
|
c@23
|
405 assert(mod(length(varargin),2)==0,'MASSEFresults:addData:invalidArgs','input must contain parameter/value pairs')
|
c@0
|
406 rI = find(ismember(dataTable.(key),keyVal),1,'first');
|
c@0
|
407 if isempty(rI) % add a new row
|
c@0
|
408 % get data from varargin
|
c@0
|
409 varnames = cell(0);
|
c@0
|
410 vals = cell(0);
|
c@0
|
411 for n = 1:2:length(varargin)
|
c@0
|
412 varnames{(n+1)/2} = varargin{n};
|
c@0
|
413 vals{(n+1)/2} = varargin{n+1};
|
c@0
|
414 end
|
c@0
|
415 % make new row
|
c@0
|
416 vars = dataTable.Properties.VariableNames;
|
c@0
|
417 newrow = cell(1,length(vars));
|
c@0
|
418 newrow{strcmp(key,vars)} = keyVal;
|
c@0
|
419 for r = 1:length(varnames)
|
c@0
|
420 if ismember(varnames{r},vars);
|
c@0
|
421 newrow{strcmp(varnames{r},vars)} = vals{r};
|
c@0
|
422 end
|
c@0
|
423 end
|
c@0
|
424 newrow = cell2table(newrow,'VariableNames',vars);
|
c@0
|
425 % append
|
c@0
|
426 dataTable = [dataTable; newrow];
|
c@0
|
427 else % update row
|
c@0
|
428 for n = 1:2:length(varargin)
|
c@0
|
429 try
|
c@0
|
430 dataTable(rI,varargin(n)) = varargin(n+1);
|
c@0
|
431 catch
|
c@0
|
432 dataTable.(varargin{n})(rI) = varargin(n+1);
|
c@0
|
433 end
|
c@0
|
434 end
|
c@0
|
435 end
|
c@0
|
436
|
c@0
|
437 end
|
c@0
|
438
|
c@0
|
439 function dataTable = findRenameVar(dataTable,old,new)
|
c@0
|
440 %FINDRENAMEVAR Find and rename a variable.
|
c@0
|
441
|
c@0
|
442 varnames = dataTable.Properties.VariableNames;
|
c@0
|
443 k = find(cellfun(@(x) ~isempty(strfind(x,old)),varnames),1,'first');
|
c@0
|
444 dataTable.Properties.VariableNames{varnames{k}} = new;
|
c@0
|
445
|
c@0
|
446 end
|
c@0
|
447
|
c@0
|
448 function dataTable = filterRows(dataTable,fhandle,col)
|
c@0
|
449 %FILTERROWS filter the rows in a table.
|
c@0
|
450
|
c@23
|
451 assert(isa(fhandle,'function_handle'),'MASSEFresults:filterRows:invalidFhandle','Parameter must be a function handle')
|
c@0
|
452 dataTable = dataTable(fhandle(dataTable.(col)),:);
|
c@0
|
453
|
c@0
|
454 end
|
c@0
|
455
|
c@0
|
456 function C = ensureKeyValParamStrs(keys,keyValArray)
|
c@0
|
457 keys = cellstr(keys);
|
c@0
|
458 C = keyValArray;
|
c@0
|
459 keyValArrayStr = cellfun(@char,keyValArray,'UniformOutput',false);
|
c@0
|
460 [~,~,ib] = intersect(keys,keyValArrayStr);
|
c@0
|
461 C(ib+1) = cellfun(@char,C(ib+1),'UniformOutput',false);
|
c@0
|
462 end
|
c@0
|
463
|
c@0
|
464 end % private static methods
|
c@0
|
465
|
c@0
|
466 end
|