Skip to main content
Skip Navigation LinksHome Extending the Spotfire Platform Creating Extensions to the Spotfire Platform Creating a Transformation Transformation: Using Properties From a Previous Transform

©Spotfire 2008

Transformation: Using Properties From a Previous Transform

This custom transformation uses properties to perform the Box-Cox transformation on all real columns using the value of the property.

This is a custom transformation which uses the properties added in the Lambda transformation example – Transformation: Setting Metadata. It performs the Box-Cox transformation on all real columns that have the Custom.Lambda property set using that value as lambda. Columns which do not have Custom.Lambda set are just sent through the transform. It also uses the Custom.Propagate property to decide if the original column also should be returned for transformed columns. The code sample only shows the reader:

private class BoxCoxTransformationReader : CustomDataRowReader { private DataRowReader inputReader; private List<DataRowReaderColumn> columns; private List<MutableValueCursor<double>> transformedCursors; private List<DataValueCursor<double>> transformInputCursors; private List<double> lambdas; public BoxCoxTransformationReader(DataRowReader inputReader) { this.inputReader = inputReader; this.transformedCursors = new List<MutableValueCursor<double>>(); this.transformInputCursors = new List<DataValueCursor<double>>(); this.lambdas = new List<double>(); this.columns = new List<DataRowReaderColumn>(); foreach (DataRowReaderColumn col in inputReader.Columns) { bool propagate = true; bool isLambda = false; DataColumnProperties properties = col.Properties; if (col.DataType == DataType.Real && col.Properties.HasPropertyValue("Custom.Lambda")) { isLambda = true; double lambda = (double)col.Properties.GetProperty("Custom.Lambda"); propagate = (bool)col.Properties.GetProperty("Custom.Propagate"); this.lambdas.Add(lambda); MutableValueCursor<double> cursor = (MutableValueCursor <double>)DataValueCursor.CreateMutableCursor(DataType.Real); this.transformedCursors.Add(cursor); this.transformInputCursors.Add( (DataValueCursor<double>)col.Cursor); this.columns.Add( new DataRowReaderColumn( col.Name, col.DataType, properties, cursor)); } if(propagate) { // does not have a lambda property. string columnName = col.Name; if(isLambda) { // add original to propagated transformed columns. columnName = string.Format("Original {0}", columnName); } this.columns.Add( new DataRowReaderColumn( columnName, col.DataType, properties, col.Cursor)); } } } protected override IEnumerable<DataRowReaderColumn> GetColumnsCore() { return this.columns; } protected override ResultProperties GetResultPropertiesCore() { return this.inputReader.ResultProperties; } protected override void ResetCore() { this.inputReader.Reset(); } protected override bool MoveNextCore() { if (!this.inputReader.MoveNext()) { return false; } for (int i = 0; i < this.transformedCursors.Count; ++i) { DataValueCursor<double> input = this.transformInputCursors[i]; MutableValueCursor<double> output = this.transformedCursors[i]; if (input.IsCurrentValueValid) { output.MutableDataValue.IsValid = true; double val = input.CurrentValue; double lambda = this.lambdas[i]; if (lambda == 0) { val = Math.Log(val); } else if(lambda != 1) { val = (Math.Pow(val, lambda) - 1) / lambda; } output.MutableDataValue.Value = val; } else { output.MutableDataValue.IsValid = false; output.MutableDataValue.ErrorValue = input.CurrentDataValue.ErrorValue; } } return true; } }