public override ValidationInfo Validate() { //go through all the column names, if any are not numeric then stop the analysis List <string> allVars = new List <string>(); allVars.AddRange(maVariables.Responses); if (maVariables.CategoricalPredictor != null) { allVars.Add(maVariables.CategoricalPredictor); } if (maVariables.ContinuousPredictors != null) { allVars.AddRange(maVariables.ContinuousPredictors); } allVars.Add(maVariables.CaseID); if (!CheckColumnNames(allVars)) { return(ValidationInfo); } if (maVariables.CategoricalPredictor != null) { if (!CheckFactorsHaveLevels(maVariables.CategoricalPredictor, true)) { return(ValidationInfo); } if (CountDistinctLevels(maVariables.CategoricalPredictor) < 2) { ValidationInfo.AddErrorMessage("At least one of your categorical predictors only has one level. Please remove it from the analysis."); return(ValidationInfo); } } //Go through each response foreach (string response in maVariables.Responses) { if (!CheckIsNumeric(response)) { ValidationInfo.AddErrorMessage("The Response (" + response + ") contains non-numeric data that cannot be processed. Please check the data and make sure it was entered correctly."); return(ValidationInfo); } CheckTransformations(maVariables.ResponseTransformation, response); //Do checks to ensure that treatments contain a response etc and the responses contain a treatment etc... if (maVariables.CategoricalPredictor != null && maVariables.AnalysisType == MultivariateAnalysisModel.AnalysisOption.LinearDiscriminantAnalysis) { //check response and cat factors contain values if (!CheckFactorAndResponseNotBlank(maVariables.CategoricalPredictor, response, ReflectionExtensions.GetPropertyDisplayName <MultivariateAnalysisModel>(i => i.CategoricalPredictor))) { return(ValidationInfo); } if (!CheckResponsesPerLevel(maVariables.CategoricalPredictor, response, ReflectionExtensions.GetPropertyDisplayName <MultivariateAnalysisModel>(i => i.CategoricalPredictor))) { return(ValidationInfo); } } //Go through each continuous predictor if (maVariables.ContinuousPredictors != null && maVariables.AnalysisType == MultivariateAnalysisModel.AnalysisOption.PartialLeastSquares) { foreach (string continuousPredictor in maVariables.ContinuousPredictors) { if (!CheckIsNumeric(continuousPredictor)) { ValidationInfo.AddErrorMessage("The continuous predictor (" + continuousPredictor + ") contains non-numeric data that cannot be processed. Please check the data and make sure it was entered correctly."); return(ValidationInfo); } else if (!CheckFactorAndResponseNotBlank(continuousPredictor, response, ReflectionExtensions.GetPropertyDisplayName <MultivariateAnalysisModel>(i => i.ContinuousPredictors))) { return(ValidationInfo); } } } //check response and cat factors contain values if (maVariables.CaseID != null && !CheckFactorAndResponseNotBlank(maVariables.CaseID, response, ReflectionExtensions.GetPropertyDisplayName <MultivariateAnalysisModel>(i => i.CaseID))) { return(ValidationInfo); } } //check that all the responses contain the same number of responses, row by row int expectedResponses = maVariables.Responses.Count(); foreach (DataRow row in DataTable.Rows) { int actualResponses = 0; foreach (string response in maVariables.Responses) { if (!String.IsNullOrEmpty(row[response].ToString())) { actualResponses++; } } if (expectedResponses != actualResponses) { ValidationInfo.AddErrorMessage("One or more of the response variables contains missing data. Please delete any rows of the dataset that contain missing data prior to running the analysis."); return(ValidationInfo); } } if (maVariables.AnalysisType == MultivariateAnalysisModel.AnalysisOption.PrincipalComponentsAnalysis) { if (maVariables.CategoricalPredictor != null) { ValidationInfo.AddWarningMessage("When performing a PCA analysis the categorical predictor you have selected will not be used. If you do need to use them in the analysis, then another analysis option may be more appropriate."); } else if (maVariables.ContinuousPredictors != null) { ValidationInfo.AddWarningMessage("When performing a PCA analysis the continuous predictors you have selected will not be used. If you do need to use them in the analysis, then another analysis option may be more appropriate."); } } else if (maVariables.AnalysisType == MultivariateAnalysisModel.AnalysisOption.ClusterAnalysis) { if (maVariables.CategoricalPredictor != null) { ValidationInfo.AddWarningMessage("When performing a Cluster analysis the categorical predictor you have selected will not be used. If you do need to use them in the analysis, then another analysis option may be more appropriate."); } if (maVariables.ContinuousPredictors != null) { ValidationInfo.AddWarningMessage("When performing a Cluster analysis the continuous predictors you have selected will not be used. If you do need to use them in the analysis, then another analysis option may be more appropriate."); } } else if (maVariables.AnalysisType == MultivariateAnalysisModel.AnalysisOption.LinearDiscriminantAnalysis) { if (maVariables.CategoricalPredictor == null) { ValidationInfo.AddErrorMessage("When performing a LDA analysis a categorical predictor is required."); } if (maVariables.ContinuousPredictors != null) { ValidationInfo.AddWarningMessage("When performing a LDA analysis the continuous predictors you have selected will not be used. If you do need to use them in the analysis, then another analysis option may be more appropriate."); } } //display the warning messages (if any) and return the result return(ValidationInfo); }
private bool CategoricalAgainstContinuousVariableChecks(List <string> categorical, string continuous) { foreach (string catFactor in categorical) //go through each categorical factor and do the check on each { string factorType; if (etVariables.Treatments.Contains(catFactor)) { factorType = ReflectionExtensions.GetPropertyDisplayName <EquivalenceTOSTTestModel>(i => i.Treatments); } else { factorType = ReflectionExtensions.GetPropertyDisplayName <EquivalenceTOSTTestModel>(i => i.OtherDesignFactors); } string responseType; if (etVariables.Response.Contains(continuous)) { responseType = ReflectionExtensions.GetPropertyDisplayName <EquivalenceTOSTTestModel>(i => i.Response); } else { responseType = ReflectionExtensions.GetPropertyDisplayName <EquivalenceTOSTTestModel>(i => i.Covariates); } //Now that the whole column checks have been done, ensure that the treatment and response for each row is ok List <string> categoricalRow = new List <string>(); List <string> continuousRow = new List <string>(); foreach (DataRow row in DataTable.Rows) //assemble a list of the categorical data and the continuous data... { categoricalRow.Add(row[catFactor].ToString()); continuousRow.Add(row[continuous].ToString()); } for (int i = 0; i < DataTable.Rows.Count; i++) //use for loop cos its easier to compare the indexes of the cat and cont rows { //Check that the "response" does not contains non-numeric data bool parsedOK = Double.TryParse(continuousRow[i], out double parsedValue); if (!String.IsNullOrEmpty(continuousRow[i]) && !parsedOK) { ValidationInfo.AddErrorMessage("The " + responseType + " (" + continuous + ") contains non-numerical data which cannot be processed. Please check the input data and make sure the data was entered correctly."); return(false); } //Check that there are no responses where the treatments are blank if (String.IsNullOrEmpty(categoricalRow[i]) && !String.IsNullOrEmpty(continuousRow[i])) { ValidationInfo.AddErrorMessage("The " + factorType + " (" + catFactor + ") contains missing data where there are observations present in the " + responseType + ". Please check the input data and make sure the data was entered correctly."); return(false); } //check that the "response" contains data for each "treatment" (not fatal) if (!String.IsNullOrEmpty(categoricalRow[i]) && String.IsNullOrEmpty(continuousRow[i])) { string mess = "The " + responseType + " (" + continuous + ") contains missing data."; if (responseType == "Covariate") { mess = mess + " Any response that does not have a corresponding covariate will be excluded from the analysis."; } ValidationInfo.AddWarningMessage(mess); } } } //if got here then all checks ok, return true return(true); }
public override ValidationInfo Validate() { //go through all the column names, if any are numeric then stop the analysis List <string> allVars = new List <string>(); allVars.AddVariables(etVariables.Treatments); allVars.AddVariables(etVariables.OtherDesignFactors); allVars.Add(etVariables.Response); allVars.AddVariables(etVariables.Covariates); if (!CheckColumnNames(allVars)) { return(ValidationInfo); } //First create a list of catogorical variables selected (i.e. as treatments and other factors) List <string> categorical = new List <string>(); categorical.AddVariables(etVariables.Treatments); categorical.AddVariables(etVariables.OtherDesignFactors); //check that the factors have at least 2 levels if (!CheckFactorsHaveLevels(categorical, true)) { return(ValidationInfo); } //Do checks to ensure that treatments contain a response etc and the responses contain a treatment etc... if (!CheckResponsesPerLevel(etVariables.Treatments, etVariables.Response, ReflectionExtensions.GetPropertyDisplayName <EquivalenceTOSTTestModel>(i => i.Treatments))) { return(ValidationInfo); } if (!CheckResponsesPerLevel(etVariables.OtherDesignFactors, etVariables.Response, ReflectionExtensions.GetPropertyDisplayName <EquivalenceTOSTTestModel>(i => i.OtherDesignFactors))) { return(ValidationInfo); } //do data checks on the treatments/other factors and response if (!CategoricalAgainstContinuousVariableChecks(categorical, etVariables.Response)) { return(ValidationInfo); } //check transformations if (etVariables.EquivalenceBoundsType == EquivalenceTOSTTestModel.EquivalenceBoundsOption.Percentage && etVariables.ComparisonType == EquivalenceTOSTTestModel.ComparisonOption.AllPairwise && etVariables.ResponseTransformation == "None") { ValidationInfo.AddWarningMessage("As you have chosen the % equivalence bounds, the actual boundaries has been calculated as a % of the overall mean of the response."); } else if (etVariables.EquivalenceBoundsType == EquivalenceTOSTTestModel.EquivalenceBoundsOption.Percentage && etVariables.ComparisonType == EquivalenceTOSTTestModel.ComparisonOption.ComparisonsToControl && etVariables.ResponseTransformation == "None") { ValidationInfo.AddWarningMessage("As you have chosen the % equivalence bounds, the actual boundaries has been calculated as a % of the selected control group."); } else if (etVariables.EquivalenceBoundsType == EquivalenceTOSTTestModel.EquivalenceBoundsOption.Absolute && etVariables.ResponseTransformation.StartsWith("Log")) { ValidationInfo.AddErrorMessage("As you have chosen to log transformed the response, the comparisons between the predicted means will be in the form of ratios. This implies that the difference between the means will be a % change and hence you should select % boundaries rather than absolute boundaries."); return(ValidationInfo); } else if (etVariables.EquivalenceBoundsType == EquivalenceTOSTTestModel.EquivalenceBoundsOption.Percentage && !etVariables.ResponseTransformation.StartsWith("Log")) { ValidationInfo.AddErrorMessage("As you have selected to [sqrt, arcsine, rank] transform the responses you should choose absolute boundaries rather than % boundaries. The absolute boundaries should be defined on the transformed scale rather than the original scale."); return(ValidationInfo); } CheckTransformations(etVariables.ResponseTransformation, etVariables.Response); if (etVariables.Covariates != null) { CheckTransformations(etVariables.CovariateTransformation, etVariables.Covariates, true); } //do data checks on the treatments/other factors and covariate (if selected) if (etVariables.Covariates != null) { foreach (string covariate in etVariables.Covariates) { if (!CategoricalAgainstContinuousVariableChecks(categorical, covariate)) { return(ValidationInfo); } } } if (etVariables.Covariates != null && String.IsNullOrEmpty(etVariables.PrimaryFactor)) { ValidationInfo.AddErrorMessage("You have selected a covariate but no primary factor is selected."); } if (etVariables.ComparisonType == EquivalenceTOSTTestModel.ComparisonOption.ComparisonsToControl && etVariables.Treatments.Count() > 1) { ValidationInfo.AddErrorMessage("You have selected to compare back to a control but this is not possible with multiple treatments."); } else if (etVariables.ComparisonType == EquivalenceTOSTTestModel.ComparisonOption.ComparisonsToControl && String.IsNullOrEmpty(etVariables.ControlGroup)) { ValidationInfo.AddErrorMessage("You have selected to compare back to a control but no control group is selected."); } if (etVariables.LowerBoundAbsolute > etVariables.UpperBoundAbsolute) { ValidationInfo.AddErrorMessage("The lower bound selected is higher than the upper bound, please check the bounds as the lower bound should be less than the upper bound."); } if (etVariables.EquivalenceBoundsType == EquivalenceTOSTTestModel.EquivalenceBoundsOption.Absolute && (etVariables.LowerBoundAbsolute.HasValue == false && etVariables.UpperBoundAbsolute.HasValue == false)) { ValidationInfo.AddErrorMessage("Absolute selected but bounds not entered."); } else if (etVariables.EquivalenceBoundsType == EquivalenceTOSTTestModel.EquivalenceBoundsOption.Percentage && (etVariables.LowerBoundPercentageChange.HasValue == false && etVariables.UpperBoundPercentageChange.HasValue == false)) { ValidationInfo.AddErrorMessage("Percentage equivelence bounds selected but no bounds entered."); } //if get here then no errors so return true return(ValidationInfo); }
public override ValidationInfo Validate() { //go through all the column names, if any are numeric then stop the analysis List <string> allVars = new List <string>(); allVars.Add(mcVariables.Treatment); allVars.Add(mcVariables.Response); if (!CheckColumnNames(allVars)) { return(ValidationInfo); } if (!CheckFactorsHaveLevels(mcVariables.Treatment)) { return(ValidationInfo); } //Check that the response does not contain non-numeric if (!CheckIsNumeric(mcVariables.Response)) { ValidationInfo.AddErrorMessage("The Response (" + mcVariables.Response + ") contains non-numerical data that cannot be processed. Please check input data and make sure the data was entered correctly."); return(ValidationInfo); } if (mcVariables.Treatment != null && !CheckResponsesPerLevel(mcVariables.Treatment, mcVariables.Response, ReflectionExtensions.GetPropertyDisplayName <ComparisonOfMeansPowerAnalysisDatasetBasedInputsModel>(i => i.Treatment))) { return(ValidationInfo); } if (!String.IsNullOrEmpty(mcVariables.Treatment) && !String.IsNullOrEmpty(mcVariables.Response)) //if a treat and response is selected... { //Check that the number of responses for each level is at least 2 Dictionary <string, int> levelResponses = ResponsesPerLevel(mcVariables.Treatment, mcVariables.Response); foreach (KeyValuePair <string, int> level in levelResponses) { if (level.Value < 2) { ValidationInfo.AddErrorMessage("There is no replication in one or more of the levels of the Treatment factor (" + mcVariables.Treatment + "). Please amend the dataset prior to running the analysis."); return(ValidationInfo); } } //check response and doses contain values if (!CheckFactorAndResponseNotBlank(mcVariables.Treatment, mcVariables.Response, "Treatment factor")) { return(ValidationInfo); } } else if (mcVariables.Treatment == null && mcVariables.Response != null && CountResponses(mcVariables.Response) == 1) //if only a response selected (doing absolute change) then check that more than 1 value is in the dataset! { ValidationInfo.AddErrorMessage("The Response (" + mcVariables.Response + ") contains only 1 value. Please select another factor."); return(ValidationInfo); } if (mcVariables.ChangeType == ChangeTypeOption.Percent) { if (String.IsNullOrEmpty(mcVariables.PercentChange)) { ValidationInfo.AddErrorMessage("Percent changes is required."); return(ValidationInfo); } else if (String.IsNullOrEmpty(mcVariables.ControlGroup)) { ValidationInfo.AddErrorMessage("You have selected % change as expected changes from control, but as you have not defined the control group it is not possible to calculate the % change."); return(ValidationInfo); } else { char[] splitters = { ',' }; string[] changes = mcVariables.PercentChange.Split(splitters, StringSplitOptions.None); //split list by comma foreach (string s in changes) { if (String.IsNullOrWhiteSpace(s)) { ValidationInfo.AddErrorMessage("The list of percent changes contains missing values, please remove any blank entries between the comma separated values."); return(ValidationInfo); } else { if (!Double.TryParse(s, out double number)) { ValidationInfo.AddErrorMessage("Percent changes has non-numeric values or the values are not comma separated."); return(ValidationInfo); } else if (number < 0) { ValidationInfo.AddErrorMessage("Percent changes has values less than zero."); return(ValidationInfo); } else if (number > 100) { ValidationInfo.AddErrorMessage("Percent changes has values greater than 100."); return(ValidationInfo); } } } } } else if (mcVariables.ChangeType == ChangeTypeOption.Absolute) { if (String.IsNullOrEmpty(mcVariables.AbsoluteChange)) { ValidationInfo.AddErrorMessage("Absolute changes is required."); return(ValidationInfo); } else { char[] splitters = { ',' }; string[] changes = mcVariables.AbsoluteChange.Split(splitters, StringSplitOptions.None); //split list by comma foreach (string s in changes) //go through list and check that is a number and is greater than 0 { if (String.IsNullOrWhiteSpace(s)) { ValidationInfo.AddErrorMessage("The list of absolute changes contains missing values, please remove any blank entries between the comma separated values."); return(ValidationInfo); } else { if (!Double.TryParse(s, out double number)) { ValidationInfo.AddErrorMessage("Absolute changes has non-numeric values or the values are not comma separated."); return(ValidationInfo); } else if (number < 0) { ValidationInfo.AddErrorMessage("Absolute changes has values less than zero."); return(ValidationInfo); } } } } } if (mcVariables.PlottingRangeType == PlottingRangeTypeOption.SampleSize) { if (!mcVariables.SampleSizeFrom.HasValue || !mcVariables.SampleSizeTo.HasValue) { ValidationInfo.AddErrorMessage("Sample Size From and To must be set"); return(ValidationInfo); } else if (mcVariables.SampleSizeFrom > mcVariables.SampleSizeTo) { ValidationInfo.AddErrorMessage("Sample Size To value must be greater than the From value."); return(ValidationInfo); } } else if (mcVariables.PlottingRangeType == PlottingRangeTypeOption.Power) { if (!mcVariables.PowerFrom.HasValue || !mcVariables.PowerTo.HasValue) { ValidationInfo.AddErrorMessage("Power From and To must be set"); return(ValidationInfo); } else if (mcVariables.PowerFrom > mcVariables.PowerTo) { ValidationInfo.AddErrorMessage("Power To value must be greater than the From value."); return(ValidationInfo); } } //if get here then no errors so return true return(ValidationInfo); }