source: trunk/sources/HeuristicLab.DataPreprocessing.Views/3.4/ManipulationView.cs @ 15110

Last change on this file since 15110 was 15110, checked in by pfleck, 2 years ago

#2709: merged branch to trunk

File size: 13.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Drawing;
25using System.Globalization;
26using System.Linq;
27using System.Text;
28using System.Windows.Forms;
29using HeuristicLab.Core.Views;
30using HeuristicLab.MainForm;
31
32namespace HeuristicLab.DataPreprocessing.Views {
33  [View("Manipulation Chart View")]
34  [Content(typeof(ManipulationContent), true)]
35  public partial class ManipulationView : ItemView {
36    private Action[] validators;
37    private Action[] manipulations;
38
39    public new ManipulationContent Content {
40      get { return (ManipulationContent)base.Content; }
41      set { base.Content = value; }
42    }
43
44    public ManipulationView() {
45      InitializeComponent();
46      cmbReplaceWith.SelectedIndex = 0;
47      tabsData.Appearance = TabAppearance.FlatButtons;
48      tabsData.ItemSize = new Size(0, 1);
49      tabsData.SizeMode = TabSizeMode.Fixed;
50      tabsPreview.Appearance = TabAppearance.FlatButtons;
51      tabsPreview.ItemSize = new Size(0, 1);
52      tabsPreview.SizeMode = TabSizeMode.Fixed;
53
54      validators = new Action[] {
55        () => ValidateDeleteColumnsInfo(),
56        () => ValidateDeleteColumnsVariance(),
57        () => ValidateDeleteRowsInfo(),
58        () => ValidateReplaceWith(),
59        () => ValidateShuffle()
60      };
61
62      manipulations = new Action[] {
63        () => Content.ManipulationLogic.DeleteColumnsWithMissingValuesGreater(GetDeleteColumnsInfo()),
64        () => Content.ManipulationLogic.DeleteColumnsWithVarianceSmaller(GetDeleteColumnsVariance()),
65        () => Content.ManipulationLogic.DeleteRowsWithMissingValuesGreater(GetRowsColumnsInfo()),
66        () => ReplaceMissingValues(),
67        () => Content.ManipulationLogic.Shuffle(shuffleSeparatelyCheckbox.Checked)
68      };
69    }
70
71    protected override void OnContentChanged() {
72      base.OnContentChanged();
73      if (Content != null) {
74        cmbVariableNames.Items.Clear();
75        foreach (var name in Content.ManipulationLogic.VariableNames) {
76          cmbVariableNames.Items.Add(name);
77        }
78        cmbVariableNames.SelectedIndex = 0;
79        CheckFilters();
80      }
81    }
82
83    protected override void RegisterContentEvents() {
84      base.RegisterContentEvents();
85      Content.FilterLogic.FilterChanged += FilterLogic_FilterChanged;
86    }
87
88    protected override void DeregisterContentEvents() {
89      Content.FilterLogic.FilterChanged -= FilterLogic_FilterChanged;
90      base.DeregisterContentEvents();
91    }
92
93    private void FilterLogic_FilterChanged(object sender, EventArgs e) {
94      if (Content != null) {
95        CheckFilters();
96      }
97    }
98
99    private void CheckFilters() {
100      if (Content.FilterLogic.IsFiltered) {
101        tabsPreview.SelectedIndex = 0;
102        lstMethods.Enabled = false;
103        tabsData.Enabled = false;
104        tabsPreview.Enabled = false;
105        lblPreviewInActive.Visible = true;
106        btnApply.Enabled = false;
107      } else {
108        lblPreviewInActive.Visible = false;
109        tabsData.Enabled = true;
110        tabsPreview.Enabled = true;
111        lstMethods.Enabled = true;
112        lstMethods_SelectedIndexChanged(null, null);
113      }
114    }
115
116    private double GetDeleteColumnsInfo() {
117      return double.Parse(txtDeleteColumnsInfo.Text);
118    }
119
120    private double GetDeleteColumnsVariance() {
121      return double.Parse(txtDeleteColumnsVariance.Text);
122    }
123
124    private double GetRowsColumnsInfo() {
125      return double.Parse(txtDeleteRowsInfo.Text);
126    }
127
128    private void ReplaceMissingValues() {
129      var allIndices = Content.SearchLogic.GetMissingValueIndices();
130      var columnIndex = cmbVariableNames.SelectedIndex;
131      var columnIndices = new Dictionary<int, IList<int>>{
132          {columnIndex,   allIndices[columnIndex]}
133      };
134
135      switch (cmbReplaceWith.SelectedIndex) {
136        case 0: //Value
137          Content.ManipulationLogic.ReplaceIndicesByValue(columnIndices, txtReplaceValue.Text);
138          break;
139        case 1: //Average
140          Content.ManipulationLogic.ReplaceIndicesByAverageValue(columnIndices);
141          break;
142        case 2: //Median
143          Content.ManipulationLogic.ReplaceIndicesByMedianValue(columnIndices);
144          break;
145        case 3: //Most Common
146          Content.ManipulationLogic.ReplaceIndicesByMostCommonValue(columnIndices);
147          break;
148        case 4: //Random
149          Content.ManipulationLogic.ReplaceIndicesByRandomValue(columnIndices);
150          break;
151      }
152    }
153
154    private void ValidateDeleteColumnsInfo() {
155      ValidateDoubleTextBox(txtDeleteColumnsInfo.Text);
156      if (btnApply.Enabled) {
157        var filteredColumns = Content.ManipulationLogic.ColumnsWithMissingValuesGreater(GetDeleteColumnsInfo());
158        int count = filteredColumns.Count;
159        int columnCount = Content.FilterLogic.PreprocessingData.Columns;
160        lblPreviewColumnsInfo.Text = string.Format("{0} column{1} of {2} ({3}) were detected with more than {4}% missing values.", count, (count > 1 || count == 0 ? "s" : ""), columnCount, string.Format("{0:F2}%", 100d / columnCount * count), txtDeleteColumnsInfo.Text);
161
162        //only display column names more than 0 and fewer than 50 are affected
163        if (count > 0 && count < 50) {
164          StringBuilder sb = new StringBuilder();
165          sb.Append(Environment.NewLine);
166          sb.Append("Columns: ");
167          sb.Append(Content.SearchLogic.VariableNames.ElementAt(filteredColumns.ElementAt(0)));
168          for (int i = 1; i < filteredColumns.Count; i++) {
169            string columnName = Content.SearchLogic.VariableNames.ElementAt(filteredColumns.ElementAt(i));
170            sb.Append(", ");
171            sb.Append(columnName);
172          }
173          sb.Append(Environment.NewLine);
174          sb.Append("Please press the button \"Apply Manipulation\" if you wish to delete those columns.");
175
176          lblPreviewColumnsInfo.Text += sb.ToString();
177        }
178
179        btnApply.Enabled = count > 0;
180      } else {
181        lblPreviewColumnsInfo.Text = "Preview not possible yet - please input the limit above.";
182      }
183    }
184
185    private void ValidateDeleteColumnsVariance() {
186      ValidateDoubleTextBox(txtDeleteColumnsVariance.Text);
187      if (btnApply.Enabled) {
188        var filteredColumns = Content.ManipulationLogic.ColumnsWithVarianceSmaller(GetDeleteColumnsVariance());
189        int count = filteredColumns.Count;
190        int columnCount = Content.FilterLogic.PreprocessingData.Columns;
191        lblPreviewColumnsVariance.Text = string.Format("{0} column{1} of {2} ({3}) were detected with a variance smaller than {4}.", count, (count > 1 || count == 0 ? "s" : ""), columnCount, string.Format("{0:F2}%", 100d / columnCount * count), txtDeleteColumnsVariance.Text);
192
193        //only display column names more than 0 and fewer than 50 are affected
194        if (count > 0 && count < 50) {
195          StringBuilder sb = new StringBuilder();
196          sb.Append(Environment.NewLine);
197          sb.Append("Columns: ");
198          sb.Append(Content.SearchLogic.VariableNames.ElementAt(filteredColumns.ElementAt(0)));
199          for (int i = 1; i < filteredColumns.Count; i++) {
200            string columnName = Content.SearchLogic.VariableNames.ElementAt(filteredColumns.ElementAt(i));
201            sb.Append(", ");
202            sb.Append(columnName);
203          }
204          sb.Append(Environment.NewLine);
205          sb.Append("Please press the button \"Apply Manipulation\" if you wish to delete those columns.");
206
207          lblPreviewColumnsVariance.Text += sb.ToString();
208        }
209
210        btnApply.Enabled = count > 0;
211      } else {
212        lblPreviewColumnsVariance.Text = "Preview not possible yet - please input the limit for the variance above.";
213      }
214    }
215
216    private void ValidateDeleteRowsInfo() {
217      ValidateDoubleTextBox(txtDeleteRowsInfo.Text);
218      if (btnApply.Enabled) {
219        int count = Content.ManipulationLogic.RowsWithMissingValuesGreater(GetRowsColumnsInfo()).Count;
220        int rowCount = Content.FilterLogic.PreprocessingData.Rows;
221        lblPreviewRowsInfo.Text = count + " row" + (count > 1 || count == 0 ? "s" : "") + " of " + rowCount + " (" + string.Format("{0:F2}%", 100d / rowCount * count) + ") were detected with more than " + txtDeleteRowsInfo.Text + "% missing values.";
222        if (count > 0) {
223          lblPreviewRowsInfo.Text += Environment.NewLine + Environment.NewLine + "Please press the button \"Apply Manipulation\" if you wish to delete those rows.";
224        } else {
225          btnApply.Enabled = false;
226        }
227      } else {
228        lblPreviewRowsInfo.Text = "Preview not possible yet - please input the limit above.";
229      }
230    }
231
232    private void ValidateReplaceWith() {
233      btnApply.Enabled = false;
234      string replaceWith = (string)cmbReplaceWith.SelectedItem;
235      int columnIndex = cmbVariableNames.SelectedIndex;
236
237      if (cmbReplaceWith.SelectedIndex == 0) {
238        string errorMessage;
239        string replaceValue = txtReplaceValue.Text;
240        if (string.IsNullOrEmpty(replaceValue)) {
241          lblPreviewReplaceMissingValues.Text = "Preview not possible yet - please input the text which will be used as replacement.";
242        } else if (!Content.ManipulationLogic.PreProcessingData.Validate(txtReplaceValue.Text, out errorMessage, columnIndex)) {
243          lblPreviewReplaceMissingValues.Text = "Preview not possible yet - " + errorMessage;
244        } else {
245          btnApply.Enabled = true;
246        }
247        replaceWith = "\"" + replaceValue + "\"";
248      } else {
249        btnApply.Enabled = true;
250      }
251      if (btnApply.Enabled) {
252        var allIndices = Content.SearchLogic.GetMissingValueIndices();
253        int count = allIndices[columnIndex].Count;
254        int cellCount = Content.FilterLogic.PreprocessingData.Rows * Content.FilterLogic.PreprocessingData.Columns;
255        lblPreviewReplaceMissingValues.Text = count + " cell" + (count > 1 || count == 0 ? "s" : "")
256          + " of " + cellCount + " (" + string.Format("{0:F2}%", 100d / cellCount * count) + ") were detected with missing values which would be replaced with " + replaceWith;
257        if (count > 0) {
258          lblPreviewReplaceMissingValues.Text += Environment.NewLine + Environment.NewLine + "Please press the button \"Apply Manipulation\" if you wish to perform the replacement.";
259        } else {
260          btnApply.Enabled = false;
261        }
262      }
263    }
264
265    private void ValidateShuffle() {
266      btnApply.Enabled = true;
267      lblShuffleProperties.Enabled = false;
268      lblShuffleProperties.Visible = false;
269      shuffleSeparatelyCheckbox.Enabled = true;
270      shuffleSeparatelyCheckbox.Visible = true;
271    }
272
273    private void lstMethods_SelectedIndexChanged(object sender, System.EventArgs e) {
274      int index = lstMethods.SelectedIndex;
275      tabsData.SelectedIndex = index + 1;
276      tabsPreview.SelectedIndex = index + 1;
277      btnApply.Enabled = false;
278
279      //in order that button is enabled if necessary input was already entered
280      if (index >= 0) {
281        validators[index]();
282      }
283    }
284
285    private void btnApply_Click(object sender, System.EventArgs e) {
286      manipulations[lstMethods.SelectedIndex]();
287      switch (lstMethods.SelectedIndex) {
288        case 0:
289          lblPreviewColumnsInfo.Text = "columns successfully deleted.";
290          break;
291        case 1:
292          lblPreviewColumnsVariance.Text = "columns successfully deleted.";
293          break;
294        case 2:
295          lblPreviewRowsInfo.Text = "rows successfully deleted.";
296          break;
297        case 3:
298          lblPreviewReplaceMissingValues.Text = "missing values successfully replaced.";
299          btnApply.Enabled = false;
300          break;
301        case 4:
302          lblPreviewShuffle.Text = "dataset shuffled successfully.";
303          btnApply.Enabled = false;
304          break;
305      }
306    }
307
308    private void ValidateDoubleTextBox(String text) {
309      btnApply.Enabled = false;
310      if (!string.IsNullOrEmpty(text)) {
311        double percent;
312        if (Double.TryParse(text, NumberStyles.Number ^ NumberStyles.AllowThousands, CultureInfo.CurrentCulture, out percent)) {
313          btnApply.Enabled = true;
314        }
315      }
316    }
317
318    private void txtDeleteColumnsInfo_TextChanged(object sender, EventArgs e) {
319      ValidateDeleteColumnsInfo();
320    }
321
322    private void txtDeleteColumnsVariance_TextChanged(object sender, EventArgs e) {
323      ValidateDeleteColumnsVariance();
324    }
325
326    private void txtDeleteRowsInfo_TextChanged(object sender, EventArgs e) {
327      ValidateDeleteRowsInfo();
328    }
329
330    private void cmbReplaceWith_SelectedIndexChanged(object sender, EventArgs e) {
331      bool isReplaceWithValueSelected = cmbReplaceWith.SelectedIndex == 0;
332      lblValueColon.Visible = isReplaceWithValueSelected;
333      txtReplaceValue.Visible = isReplaceWithValueSelected;
334      ValidateReplaceWith();
335    }
336
337    private void txtReplaceValue_TextChanged(object sender, EventArgs e) {
338      ValidateReplaceWith();
339    }
340  }
341}
Note: See TracBrowser for help on using the repository browser.