t-Test Function Equivalent to Excels™ TTEST?

 


Question:

Is there a function in the SDL suite that is equivalent to Excels™ TTEST(array, array, df, sides)? I would like to perform a t-test on two arrays using Delphi 6 but I don't see this function.

Answer:

Currently (release 7.2 as of March 2003) the unit STATIS does not contain any direct equivalent. However, the next release will offer such a function. Following is the source code of this function (uses the units VECTOR, MATH2, and STATIS):

(******************************************************************************)
function Perform2SampleTTest (Data1, Data2: TVector; TestType: TtTestVersion;
                              OneSided: boolean; var Mean1, Mean2, Stdv1, Stdv2,
                              MeanDiff, StdDiff, tStatistic: double;
                              var df: integer): double; overload;
(******************************************************************************
  ENTRY: Data1, Data2 ..... data vectors
         TestType ......... type of t-test to be performed
         OneSided ......... one-sided / two-sided problem

  EXIT:  Mean1, Mean2 ..... means of the two samples
         Stdv1, Stdv2 ..... standard deviations of the two samples
         MeanDiff ......... mean of paired differences
         StdDiff .......... standard deviation of paired differences
         tStatistic ....... t statistic
         df ............... degrees of freedom
         function returns the probability associated with a 2-sample t-Test
         (probability which indicates the likelyhood that two samples have come
         from the same two underlying populations having the same mean)
 ******************************************************************************)

var
  Stat1        : TCurveFit;
  StdvPooled   : double;
  Numd1, Numd2 : longint;
  i,j          : integer;
  ddummy       : double;

begin
Stat1 := TCurveFit.Create (nil);
if TestType = ttPaired
  then begin
       if Data1.NrOfElem <> Data2.NrOfElem then
         raise ESDLStatisError.Create ('Perform2SampleTTest: paired t-test requires equal number of data points');
       for i:=1 to Data1.NrOfElem do
         Stat1.EnterStatValue (Data1[i],Data2[i]);
       Stat1.CalcStatistics (numd1, Mean1, Mean2, Stdv1, Stdv2, Meandiff, StdDiff, ddummy);
       end
  else begin
       for i:=1 to Data1.NrOfElem do
         Stat1.EnterStatValue (Data1[i],0);
       Stat1.CalcStatistics (numd1, Mean1, ddummy, Stdv1, ddummy, ddummy, ddummy, ddummy);
       Stat1.Init;
       for i:=1 to Data2.NrOfElem do
         Stat1.EnterStatValue (Data2[i],0);
       Stat1.CalcStatistics (numd2, Mean2, ddummy, Stdv2, ddummy, ddummy, ddummy, ddummy);
       end;
Stat1.Free;
case Testtype of
           ttPaired : begin   // paired t-test
                      if (NumD1 = 0) then
                        raise ESDLStatisError.Create ('Perform2SampleTTest: number of data points is zero');
                      if (StdDiff  = 0) then
                        raise ESDLStatisError.Create ('Perform2SampleTTest: standard deviation of paired is zero');
                      tstatistic := abs(MeanDiff)/StdDiff*sqrt(Numd1);
                      df := Numd1-1;
                      end;
    ttHomoScedastic : begin   // 2-sample t-test
                      if (NumD1 = 0) or (NumD2 = 0) then
                        raise ESDLStatisError.Create ('Perform2SampleTTest: number of data points is zero');
                      StdvPooled := sqrt(((Numd1-1)*Stdv1*Stdv1 + (Numd2-1)*Stdv2*Stdv2)/(Numd1+Numd2-2));
                      if (StdvPooled = 0) then
                        raise ESDLStatisError.Create ('Perform2SampleTTest: pooled standard deviation is zero');
                      tstatistic := (Mean1-Mean2)/(StdvPooled*sqrt(1/Numd1+1/Numd2));
                      df := Numd1 + Numd2 - 2;
                      end;
  ttHeteroScedastic : begin   // Welch test
                      if (NumD1 = 0) or (NumD2 = 0) then
                        raise ESDLStatisError.Create ('Perform2SampleTTest: number of data points is zero');
                      StdvPooled := Stdv1*Stdv1/NumD1 + Stdv2*Stdv2/NumD2;
                      if (StdvPooled = 0) then
                        raise ESDLStatisError.Create ('Perform2SampleTTest: pooled standard deviation is zero');
                      tstatistic := abs(Mean1-Mean2)/sqrt(StdvPooled);
                      df := trunc (sqr(StdvPooled)/((sqr(Stdv1*Stdv1/NumD1)/(NumD1-1))+(sqr(Stdv2*Stdv2/NumD2)/(NumD2-1))));
                      end;
end;
result := tDistriIntegral(tstatistic,df);
if result > 0.5 then
  result := 1-result;
if not OneSided then
  result := result*2;
end;



(******************************************************************************)
function Perform2SampleTTest (Data1, Data2: TVector; TestType: TtTestVersion;
                       OneSided: boolean): double; overload;
(******************************************************************************
  ENTRY:  Data1, Data2 ..... data vectors
          TestType ......... type of t-test to be performed
          OneSided ......... one-sided / two-sided problem

  EXIT:   function returns the probability associated with a 2-sample t-Test
          (probability which indicates the likelyhood that two samples have come
          from the same two underlying populations having the same mean)

  REMARK: This function mimicks the function TTEST of Excel. If the TestType is
          set to ttHeteroScedastic the Welch approximation is used yielding
          probabilities which are slightly different to the results obtained
          from Excel.
 ******************************************************************************)

var
  Mean1      : double;
  Mean2      : double;
  Stdv1      : double;
  Stdv2      : double;
  MeanDiff   : double;
  StdDiff    : double;
  tStatistic : double;
  df         : integer;

begin
result := Perform2SampleTTest (Data1, Data2, TestType, OneSided, Mean1, Mean2,
                               Stdv1, Stdv2, MeanDiff, StdDiff, tStatistic, df);
end;