Imports System Imports System.Collections Imports CenterSpace.NMath.Core Namespace CenterSpace.NMath.Examples.VisualBasic A .NET example in Visual Basic showing some of the advanced features of the class TwoWayAnova. Module AdvancedTwoWayAnovaExample Private MaterialColumnName_ As String = "Material" Private TempColumnName_ As String = "Temperature" Private LifetimeColumnName_ As String = "Lifetime" Sub Main() Create the DataFrame that will hold the data to analyze. The variable being measured is battery lifetime. The two factors are material and temperature. The data must have at least three columns. One column must be numeric and contain the values of the variable being measured, battery life in this case, the other two columns must contain the values of the two factors that correspond to the measurement. Thus a row of the the DataFrame that we are going to use contains a value for the battery material (M1, M2, or M3), a temperature (15, 70, or 175), and a lifetime (in hours). The method CreateBatteryData() builds the DataFrame. Dim BatteryData As DataFrame = CreateBatteryData() Now create a TwoWayAnova object from the battery data. The three integer arguments indicate the following column indices, respectively: index of the column containing factor A, index of the column containing factor B, index of the column containing the measured values. Dim Anova As TwoWayAnova = New TwoWayAnova(BatteryData, 0, 1, 2) Class TwoWayAnova provides access to the data in a particular cell. A cell is defined by the values of the two factors. For example, the following code prints out all the battery lifetimes for batteries made from material M2 at temperature 70. Dim MTwoSeventyValues As DFNumericColumn = Anova.GetCellData(MaterialColumnName_, "M2", TempColumnName_, "70") Console.WriteLine() Console.WriteLine("Lifetimes of M2 batteries at 70 degrees: " & MTwoSeventyValues.ToString()) You can also get the means for each cell: Dim Mean As Double = Anova.GetMeanForCell(MaterialColumnName_, "M2", TempColumnName_, "70") Console.WriteLine("Mean lifetime of M2 batteries at 70 degrees: " & Mean) Means for a given factor level can also be accessed. For example, the following code gets the mean lifetime for all batteries made from material M1 Mean = Anova.GetMeanForFactorLevel(MaterialColumnName_, "M1") Console.WriteLine("Mean lifetime for M1 batteries = " & Mean) You can also get the grand mean. Console.WriteLine("Overall mean lifetime is " & Anova.GrandMean) Console.WriteLine() The TwoWayAnovaTable class is used to access all the traditional two way ANOVA data. Dim AnovaTable As TwoWayAnovaTable = Anova.AnovaTable Console.Write("Source: ") Console.WriteLine(MaterialColumnName_) Console.WriteLine(" Degrees of Freedom: " & AnovaTable.DegreesOfFreedom(MaterialColumnName_)) Console.WriteLine(" Sum of Squares : " & AnovaTable.SumOfSquares(MaterialColumnName_)) Console.WriteLine(" Mean Square : " & AnovaTable.MeanSquare(MaterialColumnName_)) Console.WriteLine(" F : " & AnovaTable.Fstatistic(MaterialColumnName_)) Console.WriteLine(" P : " & AnovaTable.FstatisticPvalue(MaterialColumnName_)) Console.WriteLine() Console.WriteLine("Source: " & TempColumnName_) Console.WriteLine(" Degrees of Freedom: " & AnovaTable.DegreesOfFreedom(TempColumnName_)) Console.WriteLine(" Sum of Squares : " & AnovaTable.SumOfSquares(TempColumnName_)) Console.WriteLine(" Mean Square : " & AnovaTable.MeanSquare(TempColumnName_)) Console.WriteLine(" F : " & AnovaTable.Fstatistic(TempColumnName_)) Console.WriteLine(" P : " & AnovaTable.FstatisticPvalue(TempColumnName_)) Console.WriteLine() Console.WriteLine("Source: Interaction") Console.WriteLine(" Degrees of Freedom: " & AnovaTable.InteractionDegreesOfFreedom) Console.WriteLine(" Sum of Squares : " & AnovaTable.InteractionSumOfSquares) Console.WriteLine(" Mean Square : " & AnovaTable.InteractionMeanSquare) Console.WriteLine(" F : " & AnovaTable.InteractionFstatistic) Console.WriteLine(" P : " & AnovaTable.InteractionFstatisticPvalue) Console.WriteLine() Console.WriteLine("Source: Error") Console.WriteLine(" Degrees of Freedom: " & AnovaTable.ErrorDegreesOfFreedom) Console.WriteLine(" Sum of Squares : " & AnovaTable.ErrorSumOfSquares) Console.WriteLine(" Mean Square : " & AnovaTable.ErrorMeanSquare) Console.WriteLine() Console.WriteLine("Total") Console.WriteLine(" Degrees of Freedom: " & AnovaTable.TotalDegreesOfFreedom) Console.WriteLine(" Sum of Squares : " & AnovaTable.TotalSumOfSquares) Console.WriteLine() Class TwoWayAnova computes a two way ANOVA using a multiple linear regression. The following function prints out details of the regression. See the function WriteRegressionInfo() for more information. Console.WriteLine("-------- Regression Information -----------") Console.WriteLine() WriteRegressionInfo(Anova) Console.WriteLine() Console.WriteLine("Press Enter Key") Console.Read() End Sub Two way ANOVAs are computed using a multiple linear regression. The details of this regression are available from the TwoWayAnova class. This functions shows how to access these details and sends the information to the Console. Private Sub WriteRegressionInfo(ByRef Anova As TwoWayAnova) A multiple linear regression is used to solve a two way ANOVA problem by creating dummy variables using an encoding. The TwoWayAnova class uses "effects" encoding to accomplish this. In effects encoding we define k - 1 dummy variables to encode k levels of the factor in interest. A dummy variable di for the the ith level is then defined as di = 1 if ith level, di = -1 if kth level, di = 0 otherwise If factor A has k levels, and factor B has m levels, there will also be (k - 1) * (m - 1) interaction variables in the regression. It follows that there will not be a regression parameter for every factor level, or interaction. In the code below you will notice that we check for a null return value when attempting to retrieve a regression parameter object for a particular factor level or interaction of factor levels. This is the reason. First print out information for the intercept parameter. The class AnovaRegressionParameter is derived from LinearRegressionParameter. It merely adds the SumOfSquares property. Dim InterceptParam As AnovaRegressionParameter = Anova.RegressionInterceptParameter Console.WriteLine("Parameter: Intercept") Console.WriteLine(" Estimate : " & InterceptParam.Value) Console.WriteLine(" Standard Error : " & InterceptParam.StandardError) Console.WriteLine(" T for H0 Parameter = 0: " & InterceptParam.TStatistic(0)) Console.WriteLine(" Prob > |T| : " & InterceptParam.TStatisticPValue(0)) Console.WriteLine(" Type I SS : " & InterceptParam.SumOfSquares) Console.WriteLine(" Variable Label: INTERCEPT") Console.WriteLine() Next print out information for the Material factor parameters. Since there is one less parameters than there are levels, well have to check for null return values from GetRegressionFactorParameter(). AnovaRegressionFactorParam is derived from AnovaRegressionParameter, and hence from LinearRegressionParameter, adding the Encoding property. Dim FactorParam As AnovaRegressionFactorParam Dim MaterialLevels() As String = {"M1", "M2", "M3"} Dim I As Integer For I = 0 To MaterialLevels.Length - 1 FactorParam = Anova.GetRegressionFactorParameter(MaterialColumnName_, MaterialLevels(I)) If FactorParam Is Nothing Then Else Console.WriteLine(String.Format("Parameter: {0}", MaterialLevels(I))) Console.WriteLine(" Estimate : " & FactorParam.Value) Console.WriteLine(" Standard Error : " & FactorParam.StandardError) Console.WriteLine(" T for H0 Parameter = 0: " & FactorParam.TStatistic(0)) Console.WriteLine(" Prob > |T| : " & FactorParam.TStatisticPValue(0)) Console.WriteLine(" Type I SS : " & FactorParam.SumOfSquares) Dim Encoding As String Encoding = " Variable Label: dummy variable = " Encoding += FactorParam.Encoding.ToString() Encoding += " if " Encoding += MaterialColumnName_ Encoding += " = " Encoding += MaterialLevels(I) Console.WriteLine(Encoding) Console.WriteLine() End If Next Now, do the same for the temperature factor parameter. Dim TempLevels() As String = {"15", "70", "125"} For I = 0 To MaterialLevels.Length - 1 FactorParam = Anova.GetRegressionFactorParameter(TempColumnName_, TempLevels(I)) If FactorParam Is Nothing Then Else Console.WriteLine(String.Format("Parameter: {0}", TempLevels(I))) Console.WriteLine(" Estimate : " & FactorParam.Value) Console.WriteLine(" Standard Error : " & FactorParam.StandardError) Console.WriteLine(" T for H0 Parameter = 0: " & FactorParam.TStatistic(0)) Console.WriteLine(" Prob > |T| : " & FactorParam.TStatisticPValue(0)) Console.WriteLine(" Type I SS : " & FactorParam.SumOfSquares) Dim Encoding As String Encoding = " Variable Label: dummy variable = " Encoding += FactorParam.Encoding.ToString() Encoding += " if " Encoding += TempColumnName_ Encoding += " = " Encoding += TempLevels(I) Console.WriteLine(Encoding) Console.WriteLine() End If Next Finally, print out information for the interaction parameters. AnovaRegressionInteractionParam is derived from AnovaRegressionParameter, and hence from LinearRegressionParameter. It does not contain an Encoding property. The value of the interaction variables is just the product of the values of their corresponding factor variables. Dim InteractionParam As AnovaRegressionInteractionParam Dim J As Integer For I = 0 To MaterialLevels.Length - 1 For J = 0 To TempLevels.Length - 1 InteractionParam = Anova.GetRegressionInteractionParameter(MaterialColumnName_, MaterialLevels(I), TempColumnName_, TempLevels(J)) If InteractionParam Is Nothing Then Else Console.WriteLine(String.Format("Parameter: {0}, {1}", MaterialLevels(I), TempLevels(J))) Console.WriteLine(" Estimate : " & InteractionParam.Value) Console.WriteLine(" Standard Error : " & InteractionParam.StandardError) Console.WriteLine(" T for H0 Parameter = 0: " & InteractionParam.TStatistic(0)) Console.WriteLine(" Prob > |T| : " & InteractionParam.TStatisticPValue(0)) Console.WriteLine(" Type I SS : " & InteractionParam.SumOfSquares) Dim Encoding As String = String.Format(" Variable Label: interaction of {0} and {1}", MaterialLevels(I), TempLevels(J)) Console.WriteLine(Encoding) Console.WriteLine() End If Next Next End Sub Private Function CreateBatteryData() As DataFrame Dim Data As New DataFrame() Data.AddColumn(New DFStringColumn(MaterialColumnName_)) Data.AddColumn(New DFStringColumn(TempColumnName_)) Dim BatteryLifetimeColumn As New DFIntColumn(LifetimeColumnName_) Data.AddColumn(BatteryLifetimeColumn) Dim RowNumber As Integer = 0 Data.AddRow(++RowNumber, "M1", "15", 130) Data.AddRow(++RowNumber, "M1", "15", 155) Data.AddRow(++RowNumber, "M1", "15", 74) Data.AddRow(++RowNumber, "M1", "15", 180) Data.AddRow(++RowNumber, "M1", "70", 34) Data.AddRow(++RowNumber, "M1", "70", 40) Data.AddRow(++RowNumber, "M1", "70", 80) Data.AddRow(++RowNumber, "M1", "70", 75) Data.AddRow(++RowNumber, "M1", "125", 20) Data.AddRow(++RowNumber, "M1", "125", 70) Data.AddRow(++RowNumber, "M1", "125", 82) Data.AddRow(++RowNumber, "M1", "125", 58) Data.AddRow(++RowNumber, "M2", "15", 150) Data.AddRow(++RowNumber, "M2", "15", 188) Data.AddRow(++RowNumber, "M2", "15", 159) Data.AddRow(++RowNumber, "M2", "15", 126) Data.AddRow(++RowNumber, "M2", "70", 136) Data.AddRow(++RowNumber, "M2", "70", 122) Data.AddRow(++RowNumber, "M2", "70", 106) Data.AddRow(++RowNumber, "M2", "70", 115) Data.AddRow(++RowNumber, "M2", "125", 25) Data.AddRow(++RowNumber, "M2", "125", 70) Data.AddRow(++RowNumber, "M2", "125", 58) Data.AddRow(++RowNumber, "M2", "125", 45) Data.AddRow(++RowNumber, "M3", "15", 138) Data.AddRow(++RowNumber, "M3", "15", 110) Data.AddRow(++RowNumber, "M3", "15", 168) Data.AddRow(++RowNumber, "M3", "15", 160) Data.AddRow(++RowNumber, "M3", "70", 174) Data.AddRow(++RowNumber, "M3", "70", 120) Data.AddRow(++RowNumber, "M3", "70", 150) Data.AddRow(++RowNumber, "M3", "70", 139) Data.AddRow(++RowNumber, "M3", "125", 96) Data.AddRow(++RowNumber, "M3", "125", 104) Data.AddRow(++RowNumber, "M3", "125", 82) Data.AddRow(++RowNumber, "M3", "125", 60) Return Data End Function End Module End Namespace← All NMath Code Examples