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