public void TestTrendRequest_IsValid_True_If_Enough_Valid_Values() { var dataList = DataList(); // Add invalid data point after 5 more recent points dataList.Add(new CoreDataSet { Value = ValueData.NullValue, Denominator = 4, Count = 8, Year = 2000 }); var trendRequest = new TrendRequest() { UnitValue = 1, ValueTypeId = ValueTypeIds.Proportion, YearRange = 1, Data = dataList }; string validationMessage = null; var isValid = trendRequest.IsValid(ref validationMessage); Assert.IsTrue(isValid, validationMessage); }
public void Write(TrendRequest trendRequest, TrendMarkerResult trendMarkerResult) { foreach (var data in trendRequest.Data) { _csvWriter.AddLine(data.AreaCode, data.Year, data.Value, data.Denominator, data.Count); } _csvWriter.AddLine("", "", "", "", "", trendMarkerResult.ChiSquare, trendMarkerResult.Slope, trendMarkerResult.Intercept, trendMarkerResult.Marker, trendMarkerResult.NumberOfPointsUsedInCalculation, trendMarkerResult.Message); }
public TrendMarkerResult GetTrendMarkerResult(IndicatorMetadata indicatorMetadata, Grouping grouping, IList<CoreDataSet> dataList) { var trendRequest = new TrendRequest { UnitValue = indicatorMetadata.Unit.Value, ValueTypeId = indicatorMetadata.ValueTypeId, Data = dataList, YearRange = grouping.YearRange, }; var result = _trendCalculator.GetResults(trendRequest); return result; }
public void TestTrendRequest_IsValid_True_If_Enough_Recent_Values() { var trendRequest = new TrendRequest() { UnitValue = 1, ValueTypeId = ValueTypeIds.Proportion, YearRange = 1, Data = DataList() }; string validationMessage = null; var isValid = trendRequest.IsValid(ref validationMessage); Assert.IsTrue(isValid, validationMessage); }
public void TestTrendRequest_IsValid_False_If_Value_Invalid() { var dataList = DataList(); dataList[0].Value = ValueData.NullValue; var trendRequest = new TrendRequest() { UnitValue = 1, ValueTypeId = ValueTypeIds.Proportion, YearRange = 1, Data = dataList }; string validationMessage = null; trendRequest.IsValid(ref validationMessage); Assert.AreEqual("Not enough data points with valid values to calculate recent trend", validationMessage); }
public void TestTrendRequestIsInvalidForYearRangeGreaterThan1() { var trendRequest = new TrendRequest() { UnitValue = 1, ValueTypeId = ValueTypeIds.Proportion, YearRange = 3 }; string validationMessage = null; trendRequest.IsValid(ref validationMessage); Assert.IsTrue(validationMessage == "The recent trend cannot be calculated for this year range"); }
public void TestTrendRequestIsInvalidForNonRelevantValueType() { var trendRequest = new TrendRequest() { UnitValue = 1, ValueTypeId = ValueTypeIds.Count, YearRange = 1 }; string validationMessage = null; trendRequest.IsValid(ref validationMessage); Assert.IsTrue(validationMessage == "The recent trend cannot be calculated for this value type"); }
public TrendMarkerResult GetResults(TrendRequest trendRequest) { return CalculateTrend(trendRequest); }
private bool IsSignificant(TrendRequest trendRequest, ref int pointsUsed, ref double chiSquare, ref string message) { chiSquare = 0.0; if (trendRequest.IsValid(ref message) == false) { pointsUsed = 0; return false; } // Chi squared confidence const double chiSquared99Point8 = 9.54953570608324; // inExcel =CHIINV(0.002,1) double chiSquaredConfidence = chiSquared99Point8; var fullDataList = trendRequest.Data.ToList(); for (int pointsToUse = MinimumNumberOfPoints; pointsToUse <= fullDataList.Count; pointsToUse++) { pointsUsed = pointsToUse; double sumOfr = 0; double sumOfn = 0; double sumOfrAndt = 0; double sumOfnAndt = 0; double sumOfnAndtSq = 0; double t = pointsUsed; var dataList = GetMostRecentDataOrderedByIncreasingYear(fullDataList, pointsToUse); foreach (var coreDataSet in dataList) { var r = coreDataSet.Count.Value; var n = coreDataSet.Denominator; sumOfr += r; sumOfn += n; sumOfrAndt += r * t; sumOfnAndt += n * t; sumOfnAndtSq += n * (t * t); t--; } var sumPart1 = ((sumOfn * sumOfrAndt) - (sumOfr * sumOfnAndt)); chiSquare = (sumOfn * (sumPart1 * sumPart1)) / (sumOfr * (sumOfn - sumOfr) * (sumOfn * sumOfnAndtSq - (sumOfnAndt * sumOfnAndt))); if (chiSquare > chiSquaredConfidence) { return true; } } return false; }
private TrendMarkerResult CalculateTrend(TrendRequest trendRequest, int pointsUsed = 0) { var message = string.Empty; var chiSquare = 0.0; // Is there a significant trend var isSignificant = IsSignificant(trendRequest, ref pointsUsed, ref chiSquare, ref message); // Trend line TrendLine trendLine; if (isSignificant) { var values = GetMostRecentDataOrderedByIncreasingYear(trendRequest.Data, pointsUsed) .Select(x => x.Value) .ToList(); trendLine = GetSlopeAndIntercept(values, trendRequest.ValueTypeId, trendRequest.UnitValue); } else { trendLine = new TrendLine(); } // Trend marker TrendMarker marker; if (isSignificant) { marker = trendLine.SlopeBeta > 0 ? TrendMarker.Increasing : TrendMarker.Decreasing; } else { marker = pointsUsed > 0 ? TrendMarker.NoChange : TrendMarker.CannotBeCalculated; } // Return results return new TrendMarkerResult() { Slope = trendLine.SlopeBeta, Intercept = trendLine.InterceptAlpha, NumberOfPointsUsedInCalculation = pointsUsed, Marker = marker, IsSignificant = isSignificant, ChiSquare = chiSquare, Message = message }; }