Skip to content

Commit 541e419

Browse files
committed
Add selection of table rows from values within a numerical column
1 parent 68aeb47 commit 541e419

File tree

4 files changed

+246
-1
lines changed

4 files changed

+246
-1
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
classdef FilterFromColumnValues < imagem.actions.CurrentTableAction
2+
% Select rows in a table based on a logical condition on column values.
3+
%
4+
% Class FilterFromColumnValues
5+
%
6+
% Example
7+
% FilterFromColumnValues
8+
%
9+
% See also
10+
%
11+
12+
% ------
13+
% Author: David Legland
14+
15+
% Created: 2020-12-23, using Matlab 9.8.0.1323502 (R2020a)
16+
% Copyright 2020 INRAE - BIA-BIBS.
17+
18+
19+
%% Properties
20+
properties
21+
end % end properties
22+
23+
24+
%% Constructor
25+
methods
26+
function obj = FilterFromColumnValues(varargin)
27+
% Constructor for FilterFromColumnValues class.
28+
29+
end
30+
31+
end % end constructors
32+
33+
34+
%% Methods
35+
methods
36+
function run(obj, frame) %#ok<INUSL>
37+
38+
% retrieve data
39+
gui = frame.Gui;
40+
table = frame.Doc.Table;
41+
42+
% initialize table name
43+
tableName = 'Table';
44+
if ~isempty(tableName)
45+
tableName = [table.Name '-sel'];
46+
end
47+
48+
% identify numeric columns
49+
inds = ~isFactor(table, 1:size(table, 2));
50+
colNames = table.ColNames(inds);
51+
52+
% get labels for operators
53+
opLabels = imagem.util.enums.RelationalOperators.allLabels;
54+
55+
% creates a new dialog, and populates it with some fields
56+
gd = imagem.gui.GenericDialog('Filter Table from values');
57+
addChoice(gd, 'Column: ', colNames, colNames{1});
58+
addChoice(gd, 'Operation: ', opLabels, opLabels{1});
59+
addNumericField(gd, 'Value: ', 0);
60+
addTextField(gd, 'New Table Name: ', tableName);
61+
62+
% displays the dialog, and waits for user
63+
showDialog(gd);
64+
% check if ok or cancel was clicked
65+
if wasCanceled(gd)
66+
return;
67+
end
68+
69+
% parse the user inputs
70+
colName = getNextString(gd);
71+
op = imagem.util.enums.RelationalOperators.fromLabel(getNextString(gd));
72+
value = getNextNumber(gd);
73+
tableName = getNextString(gd);
74+
75+
% select the rows that fullfil the condition
76+
column = table(:, colName);
77+
inds = apply(op, column.Data, value);
78+
79+
% create new tables
80+
tab2 = table(inds, :);
81+
tab2.Name = tableName;
82+
[frame2, doc2] = createTableFrame(gui, tab2, frame);
83+
84+
% add to history
85+
string = sprintf('%s = %s(%s(''%s'') %s %d, :);\n', ...
86+
doc2.Tag, frame.Doc.Tag, frame.Doc.Tag, colName, op.Symbol, value);
87+
addToHistory(frame2, string);
88+
string = sprintf('%s.Name = ''%s'';\n', doc2.Tag, tableName);
89+
addToHistory(frame2, string);
90+
end
91+
end % end methods
92+
93+
end % end classdef
94+

ImageM/+imagem/+actions/+table/+edit/SelectTableColumns.m

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,19 +36,23 @@
3636
methods
3737
function run(obj, frame) %#ok<INUSL>
3838

39+
% retrieve data
3940
gui = frame.Gui;
4041
table = frame.Doc.Table;
4142

43+
% open dialog to select relevant columns
4244
[sel, ok] = listdlg('ListString', table.ColNames, ...
4345
'Name', 'Select Columns', ...
4446
'PromptString', 'Select the columns:', ...
4547
'ListSize', gui.Options.DlgListSize, ...
4648
'selectionmode', 'multiple');
4749

50+
% check cancel
4851
if ~ok || isempty(sel)
4952
return;
5053
end
5154

55+
% create new table
5256
tab2 = table(:, sel);
5357
[frame2, doc2] = createTableFrame(gui, tab2, frame);
5458

@@ -57,7 +61,6 @@ function run(obj, frame) %#ok<INUSL>
5761
string = sprintf('%s = %s(:, %s);\n', ...
5862
doc2.Tag, frame.Doc.Tag, indsString);
5963
addToHistory(frame2, string);
60-
6164
end
6265
end % end methods
6366

ImageM/+imagem/+gui/FrameMenuBuilder.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,7 @@ function buildTableFrameMenu(obj, hf)
384384
addMenuItem(obj, editMenu, Concatenate(), 'Concatenate...');
385385
addMenuItem(obj, editMenu, SelectTableRows(), 'Select Rows...', 'Separator', 'On');
386386
addMenuItem(obj, editMenu, SelectTableColumns(), 'Select Columns...');
387+
addMenuItem(obj, editMenu, FilterFromColumnValues(), 'Filter From Column Values...');
387388
addMenuItem(obj, editMenu, FoldTableToImage(), 'Fold Table To Image...', 'Separator', 'On');
388389

389390
% Plot menu
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
classdef RelationalOperators
2+
% Enumeration of relational operators.
3+
%
4+
% Enumeration imagem.util.enums.RelationalOperators
5+
%
6+
% Example
7+
% % pick an enumeration
8+
% op = imagem.util.enums.RelationalOperators.GreaterThan;
9+
% % apply it onto numerical values
10+
% res = apply(op, 1:10, 4)
11+
% res =
12+
% 1x10 logical array
13+
% 0 0 0 0 1 1 1 1 1 1
14+
%
15+
% See also
16+
%
17+
18+
% ------
19+
% Author: David Legland
20+
21+
% Created: 2020-12-23, using Matlab 9.8.0.1323502 (R2020a)
22+
% Copyright 2020 INRAE - BIA-BIBS.
23+
24+
25+
%% Enumerates the different cases
26+
enumeration
27+
Equal('Equal (==)', @eq, '==');
28+
GreaterThanOrEqual('Greater Than or Equal (>=)', @ge, '>=');
29+
GreaterThan('Greater Than (>)', @gt, '>');
30+
LesserThanOrEqual('Lesser Than or Equal (<=)', @le, '<=');
31+
LesserThan('Lesser Than (<)', @lt, '<');
32+
NotEqual('Not Equal (~=)', @ne, '~=');
33+
end % end properties
34+
35+
36+
%% Static methods
37+
methods (Static)
38+
function res = allNames()
39+
% Returns a cell list with all enumeration names.
40+
mc = ?imagem.util.enums.RelationalOperators;
41+
itemList = mc.EnumerationMemberList;
42+
nItems = length(itemList);
43+
res = cell(1, nItems);
44+
45+
for i = 1:nItems
46+
% retrieve current enumeration item
47+
mitem = itemList(i);
48+
res{i} = mitem.Name;
49+
end
50+
end
51+
52+
function res = fromName(name)
53+
% Identifies a imagem.util.enums.RelationalOperators from its name.
54+
if nargin == 0 || ~ischar(name)
55+
error('requires a character array as input argument');
56+
end
57+
58+
mc = ?imagem.util.enums.RelationalOperators;
59+
itemList = mc.EnumerationMemberList;
60+
for i = 1:length(itemList)
61+
% retrieve current enumeration item
62+
mitem = itemList(i);
63+
item = imagem.util.enums.RelationalOperators.(mitem.Name);
64+
if strcmpi(name, char(item))
65+
res = item;
66+
return;
67+
end
68+
end
69+
70+
error('Unrecognized imagem.util.enums.RelationalOperators name: %s', name);
71+
end
72+
73+
function res = allLabels()
74+
% Returns a cell list with all enumeration names.
75+
mc = ?imagem.util.enums.RelationalOperators;
76+
itemList = mc.EnumerationMemberList;
77+
nItems = length(itemList);
78+
res = cell(1, nItems);
79+
80+
for i = 1:nItems
81+
% retrieve current enumeration item
82+
mitem = itemList(i);
83+
item = imagem.util.enums.RelationalOperators.(mitem.Name);
84+
res{i} = item.Label;
85+
end
86+
end
87+
88+
function res = fromLabel(label)
89+
% Identifies a imagem.util.enums.RelationalOperators from its label.
90+
if nargin == 0 || ~ischar(label)
91+
error('requires a character array as input argument');
92+
end
93+
94+
mc = ?imagem.util.enums.RelationalOperators;
95+
itemList = mc.EnumerationMemberList;
96+
for i = 1:length(itemList)
97+
% retrieve current enumeration item
98+
mitem = itemList(i);
99+
item = imagem.util.enums.RelationalOperators.(mitem.Name);
100+
if strcmpi(label, item.Label)
101+
res = item;
102+
return;
103+
end
104+
end
105+
106+
error('Unrecognized imagem.util.enums.RelationalOperators label: %s', label);
107+
end
108+
end % end methods
109+
110+
111+
%% Constructor
112+
methods
113+
function obj = RelationalOperators(label, op, symbol)
114+
% Constructor for imagem.util.enums.RelationalOperators class.
115+
obj.Label = label;
116+
obj.Op = op;
117+
obj.Symbol = symbol;
118+
end
119+
120+
end % end constructors
121+
122+
%% Methods
123+
methods
124+
function res = apply(obj, arg1, arg2)
125+
% Apply the selected operator to a pair of numerical arguments.
126+
%
127+
% op = imagem.util.enums.RelationalOperators.GreaterThan;
128+
% res = apply(op, 1:10, 4)
129+
% res =
130+
% 1x10 logical array
131+
% 0 0 0 0 1 1 1 1 1 1
132+
res = obj.Op(arg1, arg2);
133+
end
134+
end
135+
136+
%% Properties
137+
properties
138+
% The label used to identify the enumeration in graphical widgets.
139+
Label;
140+
% The operation to apply on numerical values.
141+
Op;
142+
% The symbol of the operation in Matlab syntax.
143+
Symbol;
144+
end % end properties
145+
146+
end % end classdef
147+

0 commit comments

Comments
 (0)