You've already forked lazarus-ccr
903 lines
34 KiB
Plaintext
903 lines
34 KiB
Plaintext
![]() |
unit AxSAnovaUnit;
|
||
|
|
||
|
{$mode objfpc}{$H+}
|
||
|
|
||
|
interface
|
||
|
|
||
|
uses
|
||
|
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
|
||
|
StdCtrls, Buttons, MainUnit, OutPutUnit, FunctionsLib, GraphLib, Globals,
|
||
|
DataProcs, contexthelpunit;
|
||
|
|
||
|
|
||
|
type
|
||
|
|
||
|
{ TAxSAnovaFrm }
|
||
|
|
||
|
TAxSAnovaFrm = class(TForm)
|
||
|
PosthocChk: TCheckBox;
|
||
|
DepInBtn: TBitBtn;
|
||
|
DepOutBtn: TBitBtn;
|
||
|
HelpBtn: TButton;
|
||
|
RepInBtn: TBitBtn;
|
||
|
RepOutBtn: TBitBtn;
|
||
|
ResetBtn: TButton;
|
||
|
CancelBtn: TButton;
|
||
|
ComputeBtn: TButton;
|
||
|
ReturnBtn: TButton;
|
||
|
PlotChk: TCheckBox;
|
||
|
GrpVar: TEdit;
|
||
|
GroupBox1: TGroupBox;
|
||
|
Label1: TLabel;
|
||
|
Label2: TLabel;
|
||
|
Label3: TLabel;
|
||
|
RepList: TListBox;
|
||
|
VarList: TListBox;
|
||
|
procedure ComputeBtnClick(Sender: TObject);
|
||
|
procedure DepInBtnClick(Sender: TObject);
|
||
|
procedure DepOutBtnClick(Sender: TObject);
|
||
|
procedure FormShow(Sender: TObject);
|
||
|
procedure HelpBtnClick(Sender: TObject);
|
||
|
procedure RepInBtnClick(Sender: TObject);
|
||
|
procedure RepOutBtnClick(Sender: TObject);
|
||
|
procedure ResetBtnClick(Sender: TObject);
|
||
|
procedure PostHocTests(NoSelected : integer; MSerr : double; dferr : integer;
|
||
|
count : integer; ColMeans : DblDyneVec; Sender: TObject);
|
||
|
procedure TUKEY(error_ms : double; { mean squared for residual }
|
||
|
error_df : double; { deg. freedom for residual }
|
||
|
value : double; { size of smallest group }
|
||
|
group_total : DblDyneVec; { sum of scores in a group }
|
||
|
group_count : DblDyneVec; { no. of cases in a group }
|
||
|
min_grp : integer; { minimum group code }
|
||
|
max_grp : integer); { maximum group code }
|
||
|
procedure SCHEFFETEST(error_ms : double; { mean squared residual }
|
||
|
group_total : DblDyneVec; { sum of scores in a group }
|
||
|
group_count : DblDyneVec; { count of cases in a group }
|
||
|
min_grp : integer; { code of first group }
|
||
|
max_grp : integer; { code of last group }
|
||
|
total_n : double); { total number of cases }
|
||
|
|
||
|
procedure Newman_Keuls(error_ms : double; { residual mean squared }
|
||
|
error_df : double; { deg. freedom for error }
|
||
|
value : double; { number in smallest group }
|
||
|
group_total : DblDyneVec; { sum of scores in a group }
|
||
|
group_count : DblDyneVec; { count of cases in a group }
|
||
|
min_grp : integer; { lowest group code }
|
||
|
max_grp : integer); { largest group code }
|
||
|
|
||
|
procedure TUKEY_KRAMER(error_ms : double; { residual mean squared }
|
||
|
error_df : double; { deg. freedom for error }
|
||
|
value : double; { number in smallest group }
|
||
|
group_total : DblDyneVec; { sum of scores in group }
|
||
|
group_count : DblDyneVec; { number of caes in group }
|
||
|
min_grp : integer; { code of lowest group }
|
||
|
max_grp : integer); { code of highst group }
|
||
|
procedure TUKEYBTEST(ErrorMS : double; // within groups error
|
||
|
ErrorDF : double; // degrees of freedom within
|
||
|
group_total : DblDyneVec; // vector of group sums
|
||
|
group_count : DblDyneVec; // vector of group n's
|
||
|
min_grp : integer; // smallest group code
|
||
|
max_grp : integer; // largest group code
|
||
|
groupsize : double); // size of groups (all equal)
|
||
|
|
||
|
private
|
||
|
{ private declarations }
|
||
|
public
|
||
|
{ public declarations }
|
||
|
end;
|
||
|
|
||
|
var
|
||
|
AxSAnovaFrm: TAxSAnovaFrm;
|
||
|
|
||
|
implementation
|
||
|
|
||
|
{ TAxSAnovaFrm }
|
||
|
|
||
|
procedure TAxSAnovaFrm.ResetBtnClick(Sender: TObject);
|
||
|
VAR i : integer;
|
||
|
begin
|
||
|
VarList.Items.Clear;
|
||
|
RepList.Items.Clear;
|
||
|
GrpVar.Text := '';
|
||
|
DepInBtn.Visible := true;
|
||
|
DepOutBtn.Visible := false;
|
||
|
RepInBtn.Visible := true;
|
||
|
RepOutBtn.Visible := false;
|
||
|
for i := 1 to NoVariables do
|
||
|
VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]);
|
||
|
PlotChk.Checked := false;
|
||
|
end;
|
||
|
|
||
|
procedure TAxSAnovaFrm.FormShow(Sender: TObject);
|
||
|
begin
|
||
|
ResetBtnClick(self);
|
||
|
end;
|
||
|
|
||
|
procedure TAxSAnovaFrm.HelpBtnClick(Sender: TObject);
|
||
|
begin
|
||
|
ContextHelpForm.HelpMessage((Sender as TButton).tag);
|
||
|
end;
|
||
|
|
||
|
procedure TAxSAnovaFrm.RepInBtnClick(Sender: TObject);
|
||
|
VAR i, index : integer;
|
||
|
begin
|
||
|
index := VarList.Items.Count;
|
||
|
i := 0;
|
||
|
while i < index do
|
||
|
begin
|
||
|
if (VarList.Selected[i]) then
|
||
|
begin
|
||
|
RepList.Items.Add(VarList.Items.Strings[i]);
|
||
|
VarList.Items.Delete(i);
|
||
|
index := index - 1;
|
||
|
i := 0;
|
||
|
end
|
||
|
else i := i + 1;
|
||
|
end;
|
||
|
RepOutBtn.Visible := true;
|
||
|
end;
|
||
|
|
||
|
procedure TAxSAnovaFrm.RepOutBtnClick(Sender: TObject);
|
||
|
VAR index : integer;
|
||
|
begin
|
||
|
index := RepList.ItemIndex;
|
||
|
if index < 0 then
|
||
|
begin
|
||
|
RepOutBtn.Visible := false;
|
||
|
exit;
|
||
|
end;
|
||
|
VarList.Items.Add(RepList.Items.Strings[index]);
|
||
|
RepList.Items.Delete(index);
|
||
|
end;
|
||
|
|
||
|
procedure TAxSAnovaFrm.DepInBtnClick(Sender: TObject);
|
||
|
VAR index : integer;
|
||
|
begin
|
||
|
index := VarList.ItemIndex;
|
||
|
GrpVar.Text := VarList.Items.Strings[index];
|
||
|
DepInBtn.Visible := false;
|
||
|
DepOutBtn.Visible := true;
|
||
|
end;
|
||
|
|
||
|
procedure TAxSAnovaFrm.ComputeBtnClick(Sender: TObject);
|
||
|
var
|
||
|
a1, a2, agrp, i, j, k, v1, totaln, NoSelected, range : integer;
|
||
|
group, col : integer;
|
||
|
p, X, f1, f2, f3, probf1, probf2, probf3, fd1, fd2, TotMean : double;
|
||
|
TotStdDev, den, maxmean, alpha : double;
|
||
|
C, StdDev : DblDyneMat;
|
||
|
squaredsumx, sumxsquared, coltot, sumsum : DblDyneVec;
|
||
|
degfree : array[1..8] of integer;
|
||
|
ColNoSelected : IntDyneVec;
|
||
|
ss :array[1..8] of double;
|
||
|
ms : array[1..8] of double;
|
||
|
coeff : array[1..6] of double;
|
||
|
N : IntDyneVec;
|
||
|
value, outline : string;
|
||
|
// parray : array[1..10] of pvector;
|
||
|
|
||
|
begin
|
||
|
SetLength(ColNoSelected,NoVariables+1);
|
||
|
if GrpVar.Text = '' then
|
||
|
Begin
|
||
|
ShowMessage('ERROR! Select a variable for between groups treatment groups');
|
||
|
exit;
|
||
|
end;
|
||
|
NoSelected := 1;
|
||
|
|
||
|
// Get between subjects group variable
|
||
|
for j := 1 to NoVariables do
|
||
|
if GrpVar.Text = OS3MainFrm.DataGrid.Cells[j,0] then ColNoSelected[0] := j;
|
||
|
v1 := ColNoSelected[0]; //A treatment (group) variable
|
||
|
|
||
|
//get minimum and maximum group codes for Treatment A
|
||
|
a1 := 1000; //atoi(MainForm.Grid.Cells[v1][1].c_str());
|
||
|
a2 := 0; //a1;
|
||
|
for i := 1 to NoCases do
|
||
|
Begin
|
||
|
if not GoodRecord(i,NoSelected,ColNoSelected) then continue;
|
||
|
group := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[v1,i])));
|
||
|
if group < a1 then a1 := group;
|
||
|
if group > a2 then a2 := group;
|
||
|
end;
|
||
|
range := a2 - a1 + 1;
|
||
|
NoSelected := RepList.Items.Count + 1;
|
||
|
k := NoSelected - 1; //Number of B (within subject) treatment levels
|
||
|
|
||
|
// allocate heap
|
||
|
SetLength(C,range+1,NoSelected+1);
|
||
|
SetLength(N,range+1);
|
||
|
SetLength(squaredsumx,range+1);
|
||
|
SetLength(coltot,NoSelected+1);
|
||
|
SetLength(sumxsquared,range+1);
|
||
|
SetLength(sumsum,range+1);
|
||
|
SetLength(StdDev,range+1,NoSelected+1);
|
||
|
|
||
|
// initialize arrays
|
||
|
for i := 0 to range-1 do
|
||
|
Begin
|
||
|
N[i] := 0;
|
||
|
squaredsumx[i] := 0.0;
|
||
|
sumxsquared[i] := 0.0;
|
||
|
sumsum[i] := 0.0;
|
||
|
for j := 0 to k-1 do C[i,j] := 0.0;
|
||
|
end;
|
||
|
for j := 0 to k-1 do coltot[j] := 0.0;
|
||
|
for i := 0 to range do
|
||
|
for j := 0 to k do
|
||
|
StdDev[i,j] := 0.0;
|
||
|
for i := 1 to 6 do coeff[i] := 0.0;
|
||
|
for i := 1 to 8 do degfree[i] := 0;
|
||
|
TotStdDev := 0.0;
|
||
|
TotMean := 0.0;
|
||
|
totaln := 0;
|
||
|
|
||
|
// Get items selected for repeated measures (B treatments)
|
||
|
for i := 0 to RepList.Items.Count - 1 do
|
||
|
Begin
|
||
|
for j := 1 to NoVariables do
|
||
|
Begin
|
||
|
if RepList.Items.Strings[i] = OS3MainFrm.DataGrid.Cells[j,0] then
|
||
|
ColNoSelected[i+1] := j;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
//Read data values and get sums and sums of squared values
|
||
|
for i := 1 to NoCases do
|
||
|
Begin
|
||
|
if not GoodRecord(i,NoSelected,ColNoSelected) then continue;
|
||
|
agrp := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[v1,i])));
|
||
|
agrp := agrp - a1 + 1; // offset to one
|
||
|
p := 0.0;
|
||
|
//Now read the B treatment scores
|
||
|
for j := 1 to k do
|
||
|
Begin
|
||
|
col := ColNoSelected[j];
|
||
|
if not GoodRecord(i,NoSelected,ColNoSelected) then continue;
|
||
|
X := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[col,i]));
|
||
|
C[agrp-1,j-1] := C[agrp-1,j-1] + X;
|
||
|
StdDev[agrp-1,j-1] := StdDev[agrp-1,j-1] + (X * X);
|
||
|
coeff[1]:= coeff[1] + X;
|
||
|
p := p + X;
|
||
|
sumxsquared[agrp-1] := sumxsquared[agrp-1] + (X * X);
|
||
|
TotMean := TotMean + X;
|
||
|
TotStdDev := TotStdDev + (X * X);
|
||
|
end;
|
||
|
N[agrp-1] := N[agrp-1] + 1;
|
||
|
squaredsumx[agrp-1] := squaredsumx[agrp-1] + (p * p);
|
||
|
sumsum[agrp-1] := sumsum[agrp-1] + p;
|
||
|
end; // next case
|
||
|
|
||
|
// Obtain sums of squares for std. dev.s of B treatments
|
||
|
for i := 1 to k do // column (B treatments)
|
||
|
for j := 1 to range do // group of A treatments
|
||
|
StdDev[range,i-1] := StdDev[range,i-1] + StdDev[j-1,i-1];
|
||
|
|
||
|
// Obtain sums of squares for std. dev.s of A treatments
|
||
|
for i := 1 to range do
|
||
|
for j := 1 to k do
|
||
|
StdDev[i-1,k] := StdDev[i-1,k] + StdDev[i-1,j-1];
|
||
|
|
||
|
// Obtain cell standard deviations
|
||
|
for i := 1 to range do // rows
|
||
|
Begin
|
||
|
for j := 1 to k do // columns
|
||
|
Begin
|
||
|
StdDev[i-1,j-1] := StdDev[i-1,j-1] - ((C[i-1,j-1] * C[i-1,j-1]) / (N[i-1]));
|
||
|
StdDev[i-1,j-1] := StdDev[i-1,j-1] / (N[i-1]-1);
|
||
|
StdDev[i-1,j-1] := sqrt(StdDev[i-1,j-1]);
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
// Obtain A treatment group standard deviations
|
||
|
for i := 1 to range do
|
||
|
Begin
|
||
|
StdDev[i-1,k] := StdDev[i-1,k] - ((sumsum[i-1] * sumsum[i-1]) / (k * N[i-1]));
|
||
|
StdDev[i-1,k] := StdDev[i-1,k] / (k * N[i-1] - 1);
|
||
|
StdDev[i-1,k] := sqrt(StdDev[i-1,k]);
|
||
|
end;
|
||
|
|
||
|
// Obtain coefficients for the sums of squares
|
||
|
for i := 1 to range do
|
||
|
Begin
|
||
|
coeff[2] := coeff[2] + sumxsquared[i-1];
|
||
|
coeff[3] := coeff[3] + ((sumsum[i-1] * (sumsum[i-1]) / ((N[i-1] * k))));
|
||
|
coeff[6] := coeff[6] + squaredsumx[i-1];
|
||
|
totaln := totaln + N[i-1];
|
||
|
end;
|
||
|
coeff[1] := (coeff[1] * coeff[1]) / (totaln * k);
|
||
|
den := k;
|
||
|
coeff[6] := coeff[6] / den;
|
||
|
for j := 1 to k do
|
||
|
Begin
|
||
|
coltot[j-1] := 0.0;
|
||
|
for i := 1 to range do
|
||
|
Begin
|
||
|
coltot[j-1] := coltot[j-1] + C[i-1,j-1];
|
||
|
coeff[5] := coeff[5] + ((C[i-1,j-1] * C[i-1,j-1]) / N[i-1]);
|
||
|
end;
|
||
|
coeff[4] := coeff[4] + (coltot[j-1] * coltot[j-1]);
|
||
|
end;
|
||
|
den := totaln;
|
||
|
coeff[4] := coeff[4] / den;
|
||
|
|
||
|
// Obtain B treatment group standard deviations
|
||
|
for j := 1 to k do
|
||
|
Begin
|
||
|
StdDev[range,j-1] := StdDev[range,j-1] - ((coltot[j-1] * coltot[j-1]) / totaln);
|
||
|
StdDev[range,j-1] := StdDev[range,j-1] / (totaln-1);
|
||
|
StdDev[range,j-1] := sqrt(StdDev[range,j-1]);
|
||
|
end;
|
||
|
|
||
|
// Calculate degrees of freedom for the mean squares
|
||
|
degfree[1] := totaln - 1; // Between subjects degrees freedom
|
||
|
degfree[2] := a2 - a1; // between groups degrees of freedom
|
||
|
degfree[3] := totaln - (a2 - a1 + 1);// subjects within groups deg. frd.
|
||
|
degfree[4] := totaln * (k - 1); // within subjects degrees of freedom
|
||
|
degfree[5] := k - 1; // B treatments degrees of freedom
|
||
|
degfree[6] := degfree[2] * degfree[5]; // A x B interaction degrees of frd.
|
||
|
degfree[7] := degfree[3] * degfree[5]; // B x Subjects within groups d.f.
|
||
|
degfree[8] := k * totaln - 1; // total degrees of freedom
|
||
|
|
||
|
// Calculate the sums of squares
|
||
|
ss[1] := coeff[6] - coeff[1];
|
||
|
ss[2] := coeff[3] - coeff[1];
|
||
|
ss[3] := coeff[6] - coeff[3];
|
||
|
ss[4] := coeff[2] - coeff[6];
|
||
|
ss[5] := coeff[4] - coeff[1];
|
||
|
ss[6] := coeff[5] - coeff[3] - coeff[4] + coeff[1];
|
||
|
ss[7] := coeff[2] - coeff[5] - coeff[6] + coeff[3];
|
||
|
ss[8] := coeff[2] - coeff[1];
|
||
|
|
||
|
// Calculate the mean squares
|
||
|
for i := 1 to 8 do
|
||
|
Begin
|
||
|
den := degfree[i];
|
||
|
ms[i] := ss[i] / den;
|
||
|
end;
|
||
|
|
||
|
// Calculate the f-tests for effects A, B and interaction
|
||
|
if (ms[3] > 0.0) then f1 := ms[2] / ms[3] else f1 := 1000.0;
|
||
|
if (ms[7] > 0.0) then
|
||
|
Begin
|
||
|
f2 := ms[5] / ms[7];
|
||
|
f3 := ms[6] / ms[7];
|
||
|
end
|
||
|
else
|
||
|
Begin
|
||
|
f2 := 1000.0;
|
||
|
f3 := 1000.0;
|
||
|
end;
|
||
|
|
||
|
//Now, report results
|
||
|
OutPutFrm.RichEdit.Clear;
|
||
|
OutPutFrm.RichEdit.Lines.Add('ANOVA With One Between Subjects and One Within Subjects Treatments');
|
||
|
OutPutFrm.RichEdit.Lines.Add('');
|
||
|
OutPutFrm.RichEdit.Lines.Add('------------------------------------------------------------------');
|
||
|
OutPutFrm.RichEdit.Lines.Add('Source df SS MS F Prob.');
|
||
|
OutPutFrm.RichEdit.Lines.Add('------------------------------------------------------------------');
|
||
|
fd1 := degfree[2];
|
||
|
fd2 := degfree[3];
|
||
|
probf1 := probf(f1, fd1, fd2);
|
||
|
fd1 := degfree[5];
|
||
|
fd2 := degfree[7];
|
||
|
probf2 := probf(f2, fd1, fd2);
|
||
|
fd1 := degfree[6];
|
||
|
fd2 := degfree[7];
|
||
|
probf3 := probf(f3, fd1, fd2);
|
||
|
outline := format('Between %5d %10.3f',[degfree[1],ss[1]]);
|
||
|
OutPutFrm.RichEdit.Lines.Add(outline);
|
||
|
outline := format(' Groups (A) %5d %10.3f %10.3f %10.3f %6.4f',
|
||
|
[degfree[2], ss[2], ms[2], f1, probf1]);
|
||
|
OutPutFrm.RichEdit.Lines.Add(outline);
|
||
|
outline := format(' Subjects w.g.%5d %10.3f %10.3f',
|
||
|
[degfree[3],ss[3],ms[3]]);
|
||
|
OutPutFrm.RichEdit.Lines.Add(outline);
|
||
|
OutPutFrm.RichEdit.Lines.Add('');
|
||
|
outline := format('Within Subjects %5d %10.3f',[degfree[4], ss[4]]);
|
||
|
OutPutFrm.RichEdit.Lines.Add(outline);
|
||
|
outline := format(' B Treatments %5d %10.3f %10.3f %10.3f %6.4f',
|
||
|
[degfree[5], ss[5], ms[5], f2, probf2]);
|
||
|
OutPutFrm.RichEdit.Lines.Add(outline);
|
||
|
outline := format(' A X B inter. %5d %10.3f %10.3f %10.3f %6.4f',
|
||
|
[degfree[6], ss[6], ms[6], f3, probf3]);
|
||
|
OutPutFrm.RichEdit.Lines.Add(outline);
|
||
|
outline := format(' B X S w.g. %5d %10.3f %10.3f',
|
||
|
[degfree[7], ss[7], ms[7]]);
|
||
|
OutPutFrm.RichEdit.Lines.Add(outline);
|
||
|
OutPutFrm.RichEdit.Lines.Add('');
|
||
|
outline := format('TOTAL %5d %10.3f',[degfree[8], ss[8]]);
|
||
|
OutPutFrm.RichEdit.Lines.Add(outline);
|
||
|
OutPutFrm.RichEdit.Lines.Add('------------------------------------------------------------------');
|
||
|
|
||
|
//Calculate and print means
|
||
|
OutPutFrm.RichEdit.Lines.Add('Means');
|
||
|
outline := 'TRT. ';
|
||
|
for i := 1 to k do
|
||
|
Begin
|
||
|
value := format('B%3d ',[i]);
|
||
|
outline := outline + value;
|
||
|
end;
|
||
|
outline := outline + 'TOTAL';
|
||
|
OutPutFrm.RichEdit.Lines.Add(outline);
|
||
|
OutPutFrm.RichEdit.Lines.Add(' A ');
|
||
|
for i := 1 to range do
|
||
|
Begin
|
||
|
for j := 1 to k do
|
||
|
C[i-1,j-1] := C[i-1,j-1] / N[i-1]; //mean of each B treatment within A treatment
|
||
|
sumsum[i-1] := sumsum[i-1] / (N[i-1] * k); //means in A treatment accross B treatments
|
||
|
end;
|
||
|
for j := 1 to k do coltot[j-1] := coltot[j-1] / totaln;
|
||
|
TotStdDev := TotStdDev - ((TotMean * TotMean) / (k * totaln));
|
||
|
TotStdDev := TotStdDev / (k * totaln - 1);
|
||
|
TotStdDev := sqrt(TotStdDev);
|
||
|
TotMean := TotMean / (k * totaln);
|
||
|
for i := 1 to range do
|
||
|
Begin
|
||
|
outline := format('%3d ',[i+a1-1]);
|
||
|
for j := 1 to k do
|
||
|
Begin
|
||
|
value := format('%7.3f',[C[i-1,j-1]]);
|
||
|
outline := outline + value;
|
||
|
end;
|
||
|
value := format('%7.3f',[sumsum[i-1]]);
|
||
|
outline := outline + value;
|
||
|
OutPutFrm.RichEdit.Lines.Add(outline);
|
||
|
end;
|
||
|
outline := 'TOTAL';
|
||
|
for j := 1 to k do
|
||
|
Begin
|
||
|
value := format('%7.3f',[coltot[j-1]]);
|
||
|
outline := outline + value;
|
||
|
end;
|
||
|
value := format('%7.3f',[TotMean]);
|
||
|
outline := outline + value;
|
||
|
OutPutFrm.RichEdit.Lines.Add(outline);
|
||
|
|
||
|
// Print standard deviations
|
||
|
OutPutFrm.RichEdit.Lines.Add('');
|
||
|
OutPutFrm.RichEdit.Lines.Add('Standard Deviations');
|
||
|
outline := 'TRT. ';
|
||
|
for i := 1 to k do
|
||
|
Begin
|
||
|
value := format('B%3d ',[i]);
|
||
|
outline := outline + value;
|
||
|
end;
|
||
|
outline := outline + 'TOTAL';
|
||
|
OutPutFrm.RichEdit.Lines.Add(outline);
|
||
|
OutPutFrm.RichEdit.Lines.Add(' A ');
|
||
|
for i := 1 to range do
|
||
|
Begin
|
||
|
outline := format('%3d ',[i+a1-1]);
|
||
|
for j := 1 to k do
|
||
|
Begin
|
||
|
value := format('%7.3f',[StdDev[i-1,j-1]]);
|
||
|
outline := outline + value;
|
||
|
end;
|
||
|
value := format('%7.3f',[StdDev[i-1,k]]);
|
||
|
outline := outline + value;
|
||
|
OutPutFrm.RichEdit.Lines.Add(outline);
|
||
|
end;
|
||
|
outline := 'TOTAL';
|
||
|
for j := 1 to k do
|
||
|
Begin
|
||
|
value := format('%7.3f',[StdDev[range,j-1]]);
|
||
|
outline := outline + value;
|
||
|
end;
|
||
|
value := format('%7.3f',[TotStdDev]);
|
||
|
outline := outline + value;
|
||
|
OutPutFrm.RichEdit.Lines.Add(outline);
|
||
|
|
||
|
OutPutFrm.ShowModal;
|
||
|
if PlotChk.Checked = true then // PlotMeans(C,range,k,this)
|
||
|
begin
|
||
|
maxmean := 0.0;
|
||
|
SetLength(GraphFrm.Ypoints,range,k);
|
||
|
SetLength(GraphFrm.Xpoints,1,k);
|
||
|
for i := 1 to range do
|
||
|
begin
|
||
|
outline := 'A ' + IntToStr(i);
|
||
|
GraphFrm.SetLabels[i] := outline;
|
||
|
for j := 1 to k do
|
||
|
begin
|
||
|
GraphFrm.Ypoints[i-1,j-1] := C[i-1,j-1];
|
||
|
if C[i-1,j-1] > maxmean then maxmean := C[i-1,j-1];
|
||
|
end;
|
||
|
end;
|
||
|
for j := 1 to k do
|
||
|
begin
|
||
|
coltot[j-1] := j;
|
||
|
GraphFrm.Xpoints[0,j-1] := j;
|
||
|
end;
|
||
|
GraphFrm.nosets := range;
|
||
|
GraphFrm.nbars := k;
|
||
|
GraphFrm.Heading := 'TREATMENTS X SUBJECT REPLICATIONS ANOVA';
|
||
|
GraphFrm.XTitle := 'WITHIN (B) TREATMENT GROUP';
|
||
|
GraphFrm.YTitle := 'Mean';
|
||
|
GraphFrm.barwideprop := 0.5;
|
||
|
GraphFrm.AutoScale := false;
|
||
|
GraphFrm.GraphType := 2; // 3d Vertical Bar Chart
|
||
|
GraphFrm.miny := 0.0;
|
||
|
GraphFrm.maxy := maxmean;
|
||
|
GraphFrm.BackColor := clYellow;
|
||
|
GraphFrm.WallColor := clBlack;
|
||
|
GraphFrm.FloorColor := clLtGray;
|
||
|
GraphFrm.ShowBackWall := true;
|
||
|
GraphFrm.ShowModal;
|
||
|
end;
|
||
|
|
||
|
if PosthocChk.Checked = true then
|
||
|
begin
|
||
|
OutPutFrm.RichEdit.Clear;
|
||
|
// Do tests for the A (between groups)
|
||
|
OutPutFrm.RichEdit.Lines.Add('');
|
||
|
OutPutFrm.RichEdit.Lines.Add('Comparisons for the Between Group Means');
|
||
|
PostHocTests(range, MS[1], degfree[1], range, sumsum, self);
|
||
|
OutPutFrm.ShowModal;
|
||
|
// Do tests for the B (repeated measures)
|
||
|
OutPutFrm.RichEdit.Clear;
|
||
|
OutPutFrm.RichEdit.Lines.Add('');
|
||
|
OutPutFrm.RichEdit.Lines.Add('Comparisons for the Repeated Measures Means');
|
||
|
PostHocTests(k, ms[4], degfree[4], NoCases, coltot, self);
|
||
|
end;
|
||
|
OutPutFrm.ShowModal;
|
||
|
// cleanup the heap
|
||
|
GraphFrm.Xpoints := nil;
|
||
|
GraphFrm.Ypoints := nil;
|
||
|
StdDev := nil;
|
||
|
sumsum := nil;
|
||
|
sumxsquared := nil;
|
||
|
coltot := nil;
|
||
|
squaredsumx := nil;
|
||
|
N := nil;
|
||
|
C := nil;
|
||
|
ColNoSelected := nil;
|
||
|
end;
|
||
|
|
||
|
procedure TAxSAnovaFrm.DepOutBtnClick(Sender: TObject);
|
||
|
begin
|
||
|
VarList.Items.Add(GrpVar.Text);
|
||
|
GrpVar.Text := '';
|
||
|
DepInBtn.Visible := true;
|
||
|
DepOutBtn.Visible := false;
|
||
|
end;
|
||
|
procedure TAxSAnovaFrm.PostHocTests(NoSelected : integer; MSerr : double; dferr : integer;
|
||
|
count : integer; ColMeans : DblDyneVec; Sender: TObject);
|
||
|
VAR
|
||
|
group_total : DblDyneVec;
|
||
|
group_count : DblDyneVec;
|
||
|
i, mingrp : integer;
|
||
|
begin
|
||
|
SetLength(group_total,NoSelected);
|
||
|
SetLength(group_count,NoSelected);
|
||
|
for i := 0 to NoSelected - 1 do
|
||
|
begin
|
||
|
group_count[i] := double(count);
|
||
|
group_total[i] := double(count) * ColMeans[i];
|
||
|
end;
|
||
|
mingrp := 1;
|
||
|
TUKEY(MSerr, dferr, count, group_total, group_count, mingrp, NoSelected);
|
||
|
TUKEY_KRAMER(MSerr, dferr, count, group_total, group_count, mingrp, NoSelected);
|
||
|
TUKEYBTEST(MSerr, dferr, group_total, group_count, mingrp,NoSelected, count);
|
||
|
SCHEFFETEST(MSerr, group_total, group_count, mingrp, NoSelected, count*NoSelected);
|
||
|
Newman_Keuls(MSerr, dferr, count, group_total, group_count, mingrp, NoSelected);
|
||
|
end;
|
||
|
procedure TAxSAnovaFrm.TUKEY(error_ms : double; { mean squared for residual }
|
||
|
error_df : double; { deg. freedom for residual }
|
||
|
value : double; { size of smallest group }
|
||
|
group_total : DblDyneVec; { sum of scores in a group }
|
||
|
group_count : DblDyneVec; { no. of cases in a group }
|
||
|
min_grp : integer; { minimum group code }
|
||
|
max_grp : integer); { maximum group code }
|
||
|
var
|
||
|
sig : boolean;
|
||
|
divisor : double;
|
||
|
df1 : integer;
|
||
|
alpha : double;
|
||
|
contrast, mean1, mean2 : double;
|
||
|
q_stat : double;
|
||
|
i,j : integer;
|
||
|
outline : string;
|
||
|
|
||
|
begin
|
||
|
// alpha := StrToFloat(BlksAnovaFrm.PostAlpha.Text);
|
||
|
alpha := 0.05;
|
||
|
OutPutFrm.RichEdit.Lines.Add('---------------------------------------------------------------');
|
||
|
OutPutFrm.RichEdit.Lines.Add(' Tukey HSD Test for Differences Between Means');
|
||
|
outline := format(' alpha selected = %4.2f',[alpha]);
|
||
|
OutPutFrm.RichEdit.Lines.Add(outline);
|
||
|
OutPutFrm.RichEdit.Lines.Add('Groups Difference Statistic Probability Significant?');
|
||
|
OutPutFrm.RichEdit.Lines.Add('---------------------------------------------------------------');
|
||
|
divisor := sqrt(error_ms / value );
|
||
|
for i := min_grp to max_grp - 1 do
|
||
|
for j := i + 1 to max_grp do
|
||
|
begin
|
||
|
outline := format('%2d - %2d ',[i,j]);
|
||
|
mean1 := group_total[i-1] / group_count[i-1];
|
||
|
mean2 := group_total[j-1] / group_count[j-1];
|
||
|
contrast := mean1 - mean2;
|
||
|
outline := outline + format('%7.3f q = ',[contrast]);
|
||
|
contrast := abs(contrast / divisor) ;
|
||
|
outline := outline + format('%6.3f ',[contrast]);
|
||
|
df1 := max_grp - min_grp + 1;
|
||
|
q_stat := STUDENT(contrast,error_df,df1);
|
||
|
outline := outline + format(' %6.4f',[q_stat]);
|
||
|
if alpha >= q_stat then sig := TRUE else sig := FALSE;
|
||
|
if sig = TRUE then outline := outline + ' YES '
|
||
|
else outline := outline + ' NO';
|
||
|
OutPutFrm.RichEdit.Lines.Add(outline);
|
||
|
end;
|
||
|
OutPutFrm.RichEdit.Lines.Add('---------------------------------------------------------------');
|
||
|
end;
|
||
|
|
||
|
procedure TAxSAnovaFrm.SCHEFFETEST(error_ms : double; { mean squared residual }
|
||
|
group_total : DblDyneVec; { sum of scores in a group }
|
||
|
group_count : DblDyneVec; { count of cases in a group }
|
||
|
min_grp : integer; { code of first group }
|
||
|
max_grp : integer; { code of last group }
|
||
|
total_n : double); { total number of cases }
|
||
|
var
|
||
|
statistic, stat_var, stat_sd : double;
|
||
|
mean1, mean2, alpha, difference, prob_scheffe, f_prob, df1, df2 : double;
|
||
|
outline : string;
|
||
|
i, j : integer;
|
||
|
begin
|
||
|
// alpha := StrToFloat(BlksAnovaFrm.PostAlpha.Text);
|
||
|
alpha := 0.05;
|
||
|
OutPutFrm.RichEdit.Lines.Add('');
|
||
|
OutPutFrm.RichEdit.Lines.Add('----------------------------------------------------------------');
|
||
|
OutPutFrm.RichEdit.Lines.Add(' Scheffe contrasts among pairs of means.');
|
||
|
outline := format(' alpha selected = %4.2f',[alpha]);
|
||
|
OutPutFrm.RichEdit.Lines.Add(outline);
|
||
|
OutPutFrm.RichEdit.Lines.Add('Group vs Group Difference Scheffe Critical Significant?');
|
||
|
OutPutFrm.RichEdit.Lines.Add(' Statistic Value');
|
||
|
OutPutFrm.RichEdit.Lines.Add('----------------------------------------------------------------');
|
||
|
alpha := 1.0 - alpha ;
|
||
|
for i:= min_grp to max_grp - 1 do
|
||
|
for j := i + 1 to max_grp do
|
||
|
begin
|
||
|
outline := format('%2d %2d ',[i,j]);
|
||
|
mean1 := group_total[i-1] / group_count[i-1];
|
||
|
mean2 := group_total[j-1] / group_count[j-1];
|
||
|
difference := mean1 - mean2;
|
||
|
outline := outline + format('%8.2f ',[difference]);
|
||
|
stat_var := error_ms *
|
||
|
( 1.0 / group_count[i-1] + 1.0 / group_count[j-1]);
|
||
|
stat_sd := sqrt(stat_var);
|
||
|
statistic := abs(difference / stat_sd);
|
||
|
outline := outline + format('%8.2f ',[statistic]);
|
||
|
df1 := max_grp - min_grp;
|
||
|
df2 := total_n - df1 + 1;
|
||
|
f_prob := fpercentpoint(alpha,round(df1),round(df2) );
|
||
|
prob_scheffe := sqrt(df1 * f_prob);
|
||
|
outline := outline + format('%8.3f ',[prob_scheffe]);
|
||
|
if statistic > prob_scheffe then outline := outline + 'YES'
|
||
|
else outline := outline + 'NO';
|
||
|
OutPutFrm.RichEdit.Lines.Add(outline);
|
||
|
end;
|
||
|
OutPutFrm.RichEdit.Lines.Add('----------------------------------------------------------------');
|
||
|
end;
|
||
|
|
||
|
|
||
|
procedure TAxSAnovaFrm.Newman_Keuls(error_ms : double; { residual mean squared }
|
||
|
error_df : double; { deg. freedom for error }
|
||
|
value : double; { number in smallest group }
|
||
|
group_total : DblDyneVec; { sum of scores in a group }
|
||
|
group_count : DblDyneVec; { count of cases in a group }
|
||
|
min_grp : integer; { lowest group code }
|
||
|
max_grp : integer); { largest group code }
|
||
|
var
|
||
|
i, j : integer;
|
||
|
temp1, temp2 : double;
|
||
|
groupno : IntDyneVec;
|
||
|
alpha : double;
|
||
|
contrast, mean1, mean2 : double;
|
||
|
q_stat : double;
|
||
|
divisor : double;
|
||
|
tempno : integer;
|
||
|
df1 : integer;
|
||
|
sig : boolean;
|
||
|
outline : string;
|
||
|
|
||
|
begin
|
||
|
SetLength(groupno,max_grp-min_grp+1);
|
||
|
for i := min_grp to max_grp do groupno[i-1] := i;
|
||
|
for i := min_grp to max_grp - 1 do
|
||
|
begin
|
||
|
for j := i + 1 to max_grp do
|
||
|
begin
|
||
|
if group_total[i-1] / group_count[i-1] >
|
||
|
group_total[j-1] / group_count[j-1] then
|
||
|
begin
|
||
|
temp1 := group_total[i-1];
|
||
|
temp2 := group_count[i-1];
|
||
|
tempno := groupno[i-1];
|
||
|
group_total[i-1] := group_total[j-1];
|
||
|
group_count[i-1] := group_count[j-1];
|
||
|
groupno[i-1] := groupno[j-1];
|
||
|
group_total[j-1] := temp1;
|
||
|
group_count[j-1] := temp2;
|
||
|
groupno[j-1] := tempno;
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
// alpha := StrToFloat(BlksAnovaFrm.PostAlpha.Text);
|
||
|
alpha := 0.05;
|
||
|
OutPutFrm.RichEdit.Lines.Add('');
|
||
|
OutPutFrm.RichEdit.Lines.Add('----------------------------------------------------------------------');
|
||
|
OutPutFrm.RichEdit.Lines.Add(' Neuman-Keuls Test for Contrasts on Ordered Means');
|
||
|
outline := format(' alpha selected = %4.2f',[alpha]);
|
||
|
OutPutFrm.RichEdit.Lines.Add(outline);
|
||
|
OutPutFrm.RichEdit.Lines.Add('');
|
||
|
OutPutFrm.RichEdit.Lines.Add('Group Mean');
|
||
|
for i := 1 to max_grp do
|
||
|
begin
|
||
|
outline := format('%3d %10.3f',[groupno[i-1],group_total[i-1] / group_count[i-1]]);
|
||
|
OutPutFrm.RichEdit.Lines.Add(outline);
|
||
|
end;
|
||
|
OutPutFrm.RichEdit.Lines.Add('');
|
||
|
OutPutFrm.RichEdit.Lines.Add('Groups Difference Statistic d.f. Probability Significant?');
|
||
|
OutPutFrm.RichEdit.Lines.Add('----------------------------------------------------------------------');
|
||
|
divisor := sqrt(error_ms / value);
|
||
|
for i := min_grp to max_grp - 1 do
|
||
|
begin
|
||
|
for j := i + 1 to max_grp do
|
||
|
begin
|
||
|
outline := format('%2d - %2d ',[groupno[i-1],groupno[j-1]]);
|
||
|
mean1 := group_total[i-1] / group_count[i-1];
|
||
|
mean2 := group_total[j-1] / group_count[j-1];
|
||
|
contrast := mean1 - mean2;
|
||
|
outline := outline + format('%7.3f q = ',[contrast]);
|
||
|
contrast := abs(contrast / divisor );
|
||
|
df1 := j - i + 1;
|
||
|
outline := outline + format('%6.3f %2d %3.0f ',[contrast,df1,error_df]);
|
||
|
q_stat := STUDENT(contrast,error_df,df1);
|
||
|
outline := outline + format(' %6.4f',[q_stat]);
|
||
|
if alpha > q_stat then sig := TRUE else sig := FALSE;
|
||
|
if sig = TRUE then outline := outline + ' YES'
|
||
|
else outline := outline + ' NO';
|
||
|
OutPutFrm.RichEdit.Lines.Add(outline);
|
||
|
end;
|
||
|
end;
|
||
|
OutPutFrm.RichEdit.Lines.Add('----------------------------------------------------------------------');
|
||
|
groupno := nil;
|
||
|
end;
|
||
|
|
||
|
procedure TAxSAnovaFrm.TUKEY_KRAMER(error_ms : double; { residual mean squared }
|
||
|
error_df : double; { deg. freedom for error }
|
||
|
value : double; { number in smallest group }
|
||
|
group_total : DblDyneVec; { sum of scores in group }
|
||
|
group_count : DblDyneVec; { number of caes in group }
|
||
|
min_grp : integer; { code of lowest group }
|
||
|
max_grp : integer); { code of highst group }
|
||
|
var
|
||
|
sig : boolean;
|
||
|
divisor : double;
|
||
|
df1 : integer;
|
||
|
alpha : double;
|
||
|
contrast, mean1, mean2 : double;
|
||
|
q_stat : double;
|
||
|
outline : string;
|
||
|
i, j : integer;
|
||
|
|
||
|
begin
|
||
|
// alpha := StrToFloat(BlksAnovaFrm.PostAlpha.Text);
|
||
|
alpha := 0.05;
|
||
|
OutPutFrm.RichEdit.Lines.Add('');
|
||
|
OutPutFrm.RichEdit.Lines.Add('---------------------------------------------------------------');
|
||
|
OutPutFrm.RichEdit.Lines.Add(' Tukey-Kramer Test for Differences Between Means');
|
||
|
outline := format(' alpha selected = %4.2f',[alpha]);
|
||
|
OutPutFrm.RichEdit.Lines.Add(outline);
|
||
|
OutPutFrm.RichEdit.Lines.Add('Groups Difference Statistic Probability Significant?');
|
||
|
OutPutFrm.RichEdit.Lines.Add('---------------------------------------------------------------');
|
||
|
for i := min_grp to max_grp - 1 do
|
||
|
for j := i + 1 to max_grp do
|
||
|
begin
|
||
|
outline := format('%2d - %2d ',[i,j]);
|
||
|
mean1 := group_total[i-1] / group_count[i-1];
|
||
|
mean2 := group_total[j-1] / group_count[j-1];
|
||
|
contrast := mean1 - mean2;
|
||
|
outline := outline + format('%7.3f q = ',[contrast]);
|
||
|
divisor := sqrt(error_ms *
|
||
|
( ( 1.0/group_count[i-1] + 1.0/group_count[j-1] ) / 2 ) );
|
||
|
contrast := abs(contrast / divisor) ;
|
||
|
outline := outline + format('%6.3f ',[contrast]);
|
||
|
df1 := max_grp - min_grp + 1;
|
||
|
q_stat := STUDENT(contrast,error_df,df1);
|
||
|
outline := outline + format(' %6.4f',[q_stat]);
|
||
|
if alpha >= q_stat then sig := TRUE else sig := FALSE;
|
||
|
if sig = TRUE then outline := outline + ' YES '
|
||
|
else outline := outline + ' NO';
|
||
|
OutPutFrm.RichEdit.Lines.Add(outline);
|
||
|
end;
|
||
|
OutPutFrm.RichEdit.Lines.Add('---------------------------------------------------------------');
|
||
|
end;
|
||
|
|
||
|
procedure TAxSAnovaFrm.TUKEYBTEST(ErrorMS : double; // within groups error
|
||
|
ErrorDF : double; // degrees of freedom within
|
||
|
group_total : DblDyneVec; // vector of group sums
|
||
|
group_count : DblDyneVec; // vector of group n's
|
||
|
min_grp : integer; // smallest group code
|
||
|
max_grp : integer; // largest group code
|
||
|
groupsize : double); // size of groups (all equal)
|
||
|
var
|
||
|
alpha : double;
|
||
|
outline : string;
|
||
|
i, j : integer;
|
||
|
df1 : double;
|
||
|
qstat : double;
|
||
|
tstat : double;
|
||
|
groupno : IntDyneVec;
|
||
|
temp1, temp2 : double;
|
||
|
tempno : integer;
|
||
|
NoGrps : integer;
|
||
|
contrast : double;
|
||
|
mean1, mean2 : double;
|
||
|
sig : string[6];
|
||
|
groups : double;
|
||
|
response : string[5];
|
||
|
divisor : double;
|
||
|
|
||
|
begin
|
||
|
SetLength(groupno,max_grp-min_grp+1);
|
||
|
// alpha := StrToFloat(BlksAnovaFrm.PostAlpha.Text);
|
||
|
alpha := 0.05;
|
||
|
OutPutFrm.RichEdit.Lines.Add('');
|
||
|
OutPutFrm.RichEdit.Lines.Add('---------------------------------------------------------------');
|
||
|
OutPutFrm.RichEdit.Lines.Add(' Tukey B Test for Contrasts on Ordered Means');
|
||
|
outline := format(' alpha selected = %4.2f',[alpha]);
|
||
|
OutPutFrm.RichEdit.Lines.Add(outline);
|
||
|
OutPutFrm.RichEdit.Lines.Add('---------------------------------------------------------------');
|
||
|
OutPutFrm.RichEdit.Lines.Add('');
|
||
|
OutPutFrm.RichEdit.Lines.Add('Groups Difference Statistic d.f. Prob.>value Significant?');
|
||
|
divisor := sqrt(ErrorMS / groupsize);
|
||
|
NoGrps := max_grp - min_grp + 1;
|
||
|
for i := min_grp to max_grp do groupno[i-1] := i;
|
||
|
for i := 1 to NoGrps - 1 do
|
||
|
begin
|
||
|
for j := i + 1 to NoGrps do
|
||
|
begin
|
||
|
if group_total[i-1] / group_count[i-1] >
|
||
|
group_total[j-1] / group_count[j-1] then
|
||
|
begin
|
||
|
temp1 := group_total[i-1];
|
||
|
temp2 := group_count[i-1];
|
||
|
tempno := groupno[i-1];
|
||
|
group_total[i-1] := group_total[j-1];
|
||
|
group_count[i-1] := group_count[j-1];
|
||
|
groupno[i-1] := groupno[j-1];
|
||
|
group_total[j-1] := temp1;
|
||
|
group_count[j-1] := temp2;
|
||
|
groupno[j-1] := tempno;
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
for i := 1 to NoGrps-1 do
|
||
|
begin
|
||
|
for j := i+1 to NoGrps do
|
||
|
begin
|
||
|
mean1 := group_total[i-1] / group_count[i-1];
|
||
|
mean2 := group_total[j-1] / group_count[j-1];
|
||
|
contrast := abs((mean1 - mean2) / divisor);
|
||
|
df1 := j - i + 1.0;
|
||
|
qstat := STUDENT(contrast,ErrorDF,df1);
|
||
|
groups := NoGrps;
|
||
|
tstat := STUDENT(contrast,ErrorDF,groups);
|
||
|
qstat := (qstat + tstat) / 2.0;
|
||
|
if alpha >= qstat then sig := 'YES' else sig := 'NO';
|
||
|
outline := format('%3d - %3d %10.3f %10.3f %4.0f,%4.0f %5.3f %s',
|
||
|
[groupno[i-1],groupno[j-1],
|
||
|
mean1-mean2,contrast,df1,ErrorDF,qstat,sig]);
|
||
|
OutPutFrm.RichEdit.Lines.Add(outline);
|
||
|
end;
|
||
|
end;
|
||
|
groupno := nil;
|
||
|
end;
|
||
|
|
||
|
initialization
|
||
|
{$I axsanovaunit.lrs}
|
||
|
|
||
|
end.
|
||
|
|