unit TtestUnit; {$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls, MainUnit, Globals, FunctionsLib, OutPutUnit, DataProcs; type { TTtestFrm } TTtestFrm = class(TForm) RadioGroup3: TRadioGroup; ResetBtn: TButton; CancelBtn: TButton; ComputeBtn: TButton; ReturnBtn: TButton; CorBetweenLabel: TLabel; Cor12: TEdit; CInterval: TEdit; Grp: TEdit; GroupCodeBtn: TRadioButton; Label1: TLabel; Memo1: TMemo; Var2: TEdit; Var1: TEdit; FirstVarLabel: TLabel; GrpLabel: TLabel; SecdVarLabel: TLabel; ListBox1: TListBox; SelVarLabel: TLabel; N2: TEdit; N1: TEdit; SampSize2Label: TLabel; SampSize1Label: TLabel; SD2: TEdit; SD1: TEdit; SD2Label: TLabel; SD1Label: TLabel; Mean2: TEdit; Mean1: TEdit; Mean2Label: TLabel; Mean1Label: TLabel; Panel1: TPanel; Panel2: TPanel; RadioGroup1: TRadioGroup; RadioGroup2: TRadioGroup; procedure ComputeBtnClick(Sender: TObject); procedure FormShow(Sender: TObject); procedure ListBox1Click(Sender: TObject); procedure RadioGroup1Click(Sender: TObject); procedure RadioGroup2Click(Sender: TObject); procedure ResetBtnClick(Sender: TObject); private { private declarations } independent : boolean; griddata : boolean; public { public declarations } end; var TtestFrm: TTtestFrm; implementation { TTtestFrm } procedure TTtestFrm.ResetBtnClick(Sender: TObject); VAR i : integer; begin RadioGroup1.ItemIndex := 0; RadioGroup2.ItemIndex := 0; Panel1.Visible := false; Panel2.Visible := true; ListBox1.Clear; Var1.Text := ''; Var2.Text := ''; Mean1.Text := ''; Mean2.Text := ''; SD1.Text := ''; SD2.Text := ''; N1.Text := ''; N2.Text := ''; Cor12.Text := ''; independent := true; griddata := false; CorBetweenLabel.Visible := false; Cor12.Visible := false; GroupCodeBtn.Checked := false; Grp.Text := ''; for i := 1 to NoVariables do ListBox1.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]); GrpLabel.Visible := false; Grp.Visible := false; Grp.Text := ''; end; procedure TTtestFrm.FormShow(Sender: TObject); begin ResetBtnClick(self); end; procedure TTtestFrm.ComputeBtnClick(Sender: TObject); var M1, M2, Dif, stddev1, stddev2, r12, z, stderr1, stderr2 : double; tequal, tunequal, cov12, lowci, hici, F, Fp, df1, df2 : double; tprobability, zprobability, stderrt, stderrz, value1, value2 : double; variance1, variance2, pooled, sedif, df, ConfInt, tconfint : double; i, j, v1, v2, ncases1, ncases2, NoSelected : integer; group, min, max : integer; ColNoSelected : IntDyneVec; response, cellstring, label1Str, label2Str, outline : string; begin SetLength(ColNoSelected,NoVariables); ncases1 := 0; ncases2 := 0; variance1 := 0.0; variance2 := 0.0; M1 := 0.0; M2 := 0.0; Dif := 0.0; r12 := 0.0; v1 := 0; v2 := 0; stddev1 := 0.0; stddev2 := 0.0; ConfInt := (100.0 - StrToFloat(CInterval.Text)) / 2.0 ; ConfInt := (100.0 - ConfInt) / 100.0; // one tail if independent then Var2.Text := Grp.Text; if griddata then // data read from grid begin for i := 1 to NoVariables do begin if Var1.Text = OS3MainFrm.DataGrid.Cells[i,0] then begin v1 := i; ColNoSelected[0] := i; label1Str := Var1.Text; end; if Var2.Text = OS3MainFrm.DataGrid.Cells[i,0] then begin v2 := i; ColNoSelected[1] := i; label2Str := Var2.Text; end; end; // next variable ncases1 := 0; ncases2 := 0; NoSelected := 2; M1 := 0.0; M2 := 0.0; variance1 := 0.0; variance2 := 0.0; r12 := 0.0; if not independent then // correlated data begin for i := 1 to NoCases do begin if not GoodRecord(i,NoSelected,ColNoSelected) then continue; ncases1 := ncases1 + 1; value1 := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[v1,i])); value2 := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[v2,i])); M1 := M1 + value1; M2 := M2 + value2; variance1 := variance1 + (value1 * value1); variance2 := variance2 + (value2 * value2); r12 := r12 + value1 * value2; end; ncases2 := ncases1; variance1 := variance1 - ((M1 * M1) / ncases1); variance1 := variance1 / (ncases1 - 1); stddev1 := sqrt(variance1); variance2 := variance2 - ((M2 * M2) / ncases2); variance2 := variance2 / (ncases2 - 1); stddev2 := sqrt(variance2); r12 := r12 - ((M1 * M2) / ncases1); r12 := r12 / (ncases1 - 1); cov12 := r12; r12 := r12 / (stddev1 * stddev2); M1 := M1 / ncases1; M2 := M2 / ncases2; Dif := M1 - M2; end; //if not independent if independent then begin if GroupCodeBtn.Checked then begin response := InputBox('Group 1','Enter the code for group 1','1'); min := StrToInt(response); response := InputBox('Group 2','Enter the code for group 2','2'); max := StrToInt(response); end else begin min := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[v2,1]))); max := min; end; for i := 2 to NoCases do begin if not GoodRecord(i,NoSelected,ColNoSelected) then continue; group := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[v2,i]))); if GroupCodeBtn.Checked = false then begin if group < min then min := group; if group > max then max := group; end; end; for i := 1 to NoCases do begin if not GoodRecord(i,NoSelected,ColNoSelected) then continue; value1 := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[v1,i])); value2 := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[v2,i])); group := round(value2); if group = min then begin M1 := M1 + value1; variance1 := variance1 + (value1 * value1); ncases1 := ncases1 + 1; end else if group = max then begin M2 := M2 + value1; variance2 := variance2 + (value1 * value1); ncases2 := Ncases2 + 1; end; end; // next case variance1 := variance1 - ((M1 * M1) / ncases1); variance1 := variance1 / (ncases1 - 1); stddev1 := sqrt(variance1); variance2 := variance2 - ((M2 * M2) / ncases2); variance2 := variance2 / (ncases2 - 1); stddev2 := sqrt(variance2); M1 := M1 / ncases1; M2 := M2 / ncases2; Dif := M1 - M2; Label1Str := format('Group %d',[min]); Label2Str := format('Group %d',[max]); end; // if independent data end; // if reading grid data if not griddata then // data read from form begin M1 := StrToFloat(Mean1.Text); M2 := StrToFloat(Mean2.Text); stddev1 := StrToFloat(SD1.Text); stddev2 := StrToFloat(SD2.Text); ncases1 := round(StrToFloat(N1.Text)); ncases2 := round(StrToFloat(N2.Text)); variance1 := stddev1 * stddev1; variance2 := stddev2 * stddev2; Label1Str := 'Group 1'; Label2Str := 'Group 2'; Dif := M1 - M2; if not independent then begin r12 := StrToFloat(Cor12.Text); cov12 := r12 * stddev1 * stddev2; end; end; // Initialize output form OutPutFrm.RichEdit.Clear; OutPutFrm.RichEdit.Lines.Add('COMPARISON OF TWO MEANS'); OutPutFrm.RichEdit.Lines.Add(''); // OutPutFrm.RichEdit.ParaGraph.Alignment := taLeftJustify; // Calculate pooled and independent t and z values and test statistic if independent then begin stderr1 := sqrt(variance1 / ncases1); Stderr2 := sqrt(variance2 / ncases2); OutPutFrm.RichEdit.Lines.Add('Variable Mean Variance Std.Dev. S.E.Mean N'); outline := format('%-10s%8.2f %8.2f %8.2f %8.2f %d', [Label1Str,M1, variance1, stddev1, stderr1, ncases1]); OutPutFrm.RichEdit.Lines.Add(outline); outline := format('%-10s%8.2f %8.2f %8.2f %8.2f %d', [Label2Str, M2, variance2, stddev2, stderr2, ncases2]); OutPutFrm.RichEdit.Lines.Add(outline); pooled := ((ncases1-1) * variance1) + ((ncases2-1) * variance2); pooled := pooled / (ncases1 + ncases2 - 2); pooled := pooled * ( 1.0 / ncases1 + 1.0 / ncases2); sedif := sqrt(pooled); tequal := dif / sedif; df := ncases1 + ncases2 - 2; tprobability := probt(tequal,df); if RadioGroup3.ItemIndex = 1 then tprobability := 0.5 * tprobability; outline := format('Assuming = variances, t = %8.3f with probability = %6.4f and %3.0f degrees of freedom', [tequal, tprobability, df]); OutPutFrm.RichEdit.Lines.Add(outline); outline := format('Difference = %8.2f and Standard Error of difference = %8.2f', [dif, sedif]); OutPutFrm.RichEdit.Lines.Add(outline); tconfint := inverset(ConfInt,df); lowci := dif - tconfint * sedif; hici := dif + tconfint * sedif; outline := format('Confidence interval = (%8.2f,%8.2f)',[lowci,hici]); OutPutFrm.RichEdit.Lines.Add(outline); // now for unequal variances sedif := sqrt((variance1 / ncases1) + (variance2 / ncases2)); tunequal := dif / sedif; df := sqr((variance1 / ncases1) + (variance2 / ncases2)); df := df / (sqr(variance1 / ncases1) / (ncases1 - 1) + sqr(variance2 / ncases2) / (ncases2 - 1) ); tprobability := probt(tequal,df); if RadioGroup3.ItemIndex = 1 then tprobability := 0.5 * tprobability; outline := format('Assuming unequal variances, t = %8.3f with probability = %6.4f and %5.2f degrees of freedom', [tunequal, tprobability, df]); OutPutFrm.RichEdit.Lines.Add(outline); outline := format('Difference = %8.2f and Standard Error of difference = %8.2f', [dif, sedif]); OutPutFrm.RichEdit.Lines.Add(outline); tconfint := inverset(ConfInt,df); lowci := dif - tconfint * sedif; hici := dif + tconfint * sedif; outline := format('Confidence interval = (%8.2f,%8.2f)',[lowci,hici]); OutPutFrm.RichEdit.Lines.Add(outline); df1 := ncases1 - 1; df2 := ncases2 - 1; if variance1 > variance2 then begin F := variance1 / variance2; Fp := probf(F,df1,df2); end else begin F := variance2 / variance1; Fp := probf(F,df2,df1); end; outline := format('F test for equal variances = %8.3f, Probability = %6.4f', [F, fp]); OutPutFrm.RichEdit.Lines.Add(outline); end else begin // dependent t test stderr1 := sqrt(variance1 / ncases1); Stderr2 := sqrt(variance2 / ncases2); OutPutFrm.RichEdit.Lines.Add('Variable Mean Variance Std.Dev. S.E.Mean N'); outline := format('%-10s%8.2f %8.2f %8.2f %8.2f %d', [Label1Str ,M1, variance1, stddev1, stderr1, ncases1]); OutPutFrm.RichEdit.Lines.Add(outline); outline := format('%-10s%8.2f %8.2f %8.2f %8.2f %d', [Label2Str,M2, variance2, stddev2, stderr2, ncases2]); OutPutFrm.RichEdit.Lines.Add(outline); sedif := variance1 + variance2 - (2.0 * cov12); sedif := sqrt(sedif / ncases1); tequal := Dif / sedif; df := ncases1 - 1; tprobability := probt(tequal,df); outline := format('Assuming dependent samples, t = %8.3f with probability = %6.4f and %3.0f degrees of freedom', [tequal, tprobability, df]); OutPutFrm.RichEdit.Lines.Add(outline); outline := format('Correlation between %s and %s = %6.3f', [Label1Str,Label2Str,r12]); OutPutFrm.RichEdit.Lines.Add(outline); outline := format('Difference = %8.2f and Standard Error of difference = %8.2f', [dif, sedif]); OutPutFrm.RichEdit.Lines.Add(outline); tconfint := inverset(ConfInt,df); lowci := dif - tconfint * sedif; hici := dif + tconfint * sedif; outline := format('Confidence interval = (%8.2f,%8.2f)', [lowci,hici]); OutPutFrm.RichEdit.Lines.Add(outline); tequal := variance1 - variance2; tequal := tequal / sqrt( (4 * variance1 * variance2)/(ncases1 - 2) * (1.0 - sqr(r12)) ); df := ncases1 - 2; tprobability := probt(tequal,df); outline := format('t for test of equal variances = %8.3f with probability = %6.4f', [tequal,tprobability]); OutPutFrm.RichEdit.Lines.Add(outline); end; OutPutFrm.ShowModal(); ColNoSelected := nil; // TtestFrm.Hide; end; procedure TTtestFrm.ListBox1Click(Sender: TObject); VAR index : integer; begin index := ListBox1.ItemIndex; if not independent then begin if Var1.Text <> '' then Var2.Text := ListBox1.Items.Strings[index] else Var1.Text := ListBox1.Items.Strings[index]; end; if independent then begin if Var1.Text <> '' then Grp.Text := ListBox1.Items.Strings[index] else Var1.Text := ListBox1.Items.Strings[index]; end; end; procedure TTtestFrm.RadioGroup1Click(Sender: TObject); VAR index : integer; begin index := RadioGroup1.ItemIndex; if index = 0 then begin Panel2.Visible := true; Panel1.Visible := false; griddata := false; end else begin Panel1.Visible := true; Panel2.Visible := false; griddata := true; if RadioGroup2.ItemIndex = 1 then begin SecdVarLabel.Visible := true; Var2.Visible := true; Grp.Visible := false; GrpLabel.Visible := false; end else begin SecdVarLabel.Visible := false; Var2.Visible := false; Grp.Visible := true; GrpLabel.Visible := true; end; end; end; procedure TTtestFrm.RadioGroup2Click(Sender: TObject); VAR index : integer; begin index := RadioGroup2.ItemIndex; if index = 0 then begin independent := true; CorBetweenLabel.Visible := false; Cor12.Visible := false; Grp.Visible := true; GrpLabel.Visible := true; GroupCodeBtn.Visible := true; SecdVarLabel.Visible := false; Var2.Visible := false; end else begin independent := false; CorBetweenLabel.Visible := true; Cor12.Visible := true; GrpLabel.Visible := false; Grp.Visible := false; GroupCodeBtn.Visible := false; SecdVarLabel.Visible := true; Var2.Visible := true; end; end; initialization {$I ttestunit.lrs} end.