# VB Advanced Two Way Anova Example

← All NMath Code Examples

```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.

Private MaterialColumnName_ As String = "Material"
Private TempColumnName_ As String = "Temperature"

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)

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.
Console.WriteLine("-------- Regression Information -----------")
Console.WriteLine()

WriteRegressionInfo(Anova)

Console.WriteLine()
Console.WriteLine("Press Enter Key")

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()

Dim RowNumber As Integer = 0