diff --git a/Orange/widgets/data/owtransform.py b/Orange/widgets/data/owtransform.py index 33a9f81d98c..9a240c3d397 100644 --- a/Orange/widgets/data/owtransform.py +++ b/Orange/widgets/data/owtransform.py @@ -1,6 +1,9 @@ -from Orange.data import Table +import numpy as np + +from Orange.data import Table, Domain from Orange.preprocess.preprocess import Preprocess, Discretize from Orange.widgets import gui +from Orange.widgets.settings import Setting from Orange.widgets.utils.sql import check_sql_input from Orange.widgets.utils.widgetpreview import WidgetPreview from Orange.widgets.widget import OWWidget, Input, Output, Msg @@ -13,6 +16,8 @@ class OWTransform(OWWidget): priority = 2110 keywords = [] + retain_all_data = Setting(False) + class Inputs: data = Input("Data", Table, default=True) preprocessor = Input("Preprocessor", Preprocess) @@ -39,6 +44,11 @@ def __init__(self): self.set_input_label_text() self.set_preprocessor_label_text() + self.retain_all_data_cb = gui.checkBox( + self.controlArea, self, "retain_all_data", label="Retain all data", + callback=self.apply + ) + def set_input_label_text(self): text = "No data on input." if self.data is not None: @@ -83,11 +93,30 @@ def apply(self): self.transformed_data = self.preprocessor(self.data) except Exception as ex: # pylint: disable=broad-except self.Error.pp_error(ex) - self.Outputs.transformed_data.send(self.transformed_data) + + if self.retain_all_data: + self.Outputs.transformed_data.send(self.merge_data()) + else: + self.Outputs.transformed_data.send(self.transformed_data) self.set_preprocessor_label_text() self.set_output_label_text() + def merge_data(self): + attributes = getattr(self.data.domain, 'attributes') + cls_vars = getattr(self.data.domain, 'class_vars') + metas_v = getattr(self.data.domain, 'metas')\ + + getattr(self.transformed_data.domain, 'attributes') + domain = Domain(attributes, cls_vars, metas_v) + X = self.data.X + Y = self.data.Y + metas = np.hstack((self.data.metas, self.transformed_data.X)) + table = Table.from_numpy(domain, X, Y, metas) + table.name = getattr(self.data, 'name', '') + table.attributes = getattr(self.data, 'attributes', {}) + table.ids = self.data.ids + return table + def send_report(self): if self.preprocessor is not None: self.report_items("Settings", diff --git a/Orange/widgets/data/tests/test_owtransform.py b/Orange/widgets/data/tests/test_owtransform.py index cd24a8c7cbd..571dd5525cd 100644 --- a/Orange/widgets/data/tests/test_owtransform.py +++ b/Orange/widgets/data/tests/test_owtransform.py @@ -76,6 +76,14 @@ def test_input_pca_preprocessor(self): self.assertIsInstance(output, Table) self.assertEqual(output.X.shape, (len(self.data), 2)) + # test retain data functionality + self.widget.retain_all_data = True + self.widget.apply() + output = self.get_output(self.widget.Outputs.transformed_data) + self.assertIsInstance(output, Table) + self.assertEqual(output.X.shape, (len(self.data), 4)) + self.assertEqual(output.metas.shape, (len(self.data), 2)) + def test_error_transforming(self): self.send_signal(self.widget.Inputs.data, self.data) self.send_signal(self.widget.Inputs.preprocessor, Preprocess())