Files
lazarus-ccr/applications/lazstats/source_orig/withinanovaunit.pas

448 lines
15 KiB
ObjectPascal
Raw Normal View History

unit WithinANOVAUnit;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
StdCtrls, Buttons, MainUnit, FunctionsLib, OutPutUnit, MatrixLib, Globals,
DataProcs, GraphLib, contexthelpunit;
type
{ TWithinANOVAFrm }
TWithinANOVAFrm = class(TForm)
AssumpChk: TCheckBox;
HelpBtn: TButton;
ResetBtn: TButton;
CancelBtn: TButton;
ComputeBtn: TButton;
ReturnBtn: TButton;
PlotChk: TCheckBox;
RelChk: TCheckBox;
GroupBox1: TGroupBox;
InBtn: TBitBtn;
Label2: TLabel;
SelList: TListBox;
OutBtn: TBitBtn;
Label1: TLabel;
VarList: TListBox;
procedure ComputeBtnClick(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure HelpBtnClick(Sender: TObject);
procedure InBtnClick(Sender: TObject);
procedure OutBtnClick(Sender: TObject);
procedure ResetBtnClick(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
var
WithinANOVAFrm: TWithinANOVAFrm;
implementation
{ TWithinANOVAFrm }
procedure TWithinANOVAFrm.ResetBtnClick(Sender: TObject);
VAR i : integer;
begin
VarList.Clear;
SelList.Clear;
PlotChk.Checked := false;
RelChk.Checked := false;
AssumpChk.Checked := false;
InBtn.Visible := true;
OutBtn.Visible := false;
for i := 1 to NoVariables do
VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]);
end;
procedure TWithinANOVAFrm.FormShow(Sender: TObject);
begin
ResetBtnClick(self);
end;
procedure TWithinANOVAFrm.HelpBtnClick(Sender: TObject);
begin
ContextHelpForm.HelpMessage((Sender as TButton).tag);
end;
procedure TWithinANOVAFrm.ComputeBtnClick(Sender: TObject);
var
i, j, k, f3 : integer;
LabelStr : string;
NoSelected, count, IER, row : integer;
SSrows, SScols, SSwrows, SSerr, SStot : double;
MSrows, MScols, MSwrows, MSerr, MStot : double;
dfrows, dfcols, dfwrows, dferr, dftot : double;
f1, f2, probf1, probf2, GrandMean, Term1, Term2, Term3, Term4 : double;
r1, r2, r3, r4, X, avgvar, avgcov : double;
determ1, determ2, M2, C2, chi2, prob : double;
errorfound : boolean;
outline : string;
Selected : IntDyneVec;
ColLabels : StrDyneVec;
ColMeans, ColVar, RowMeans, RowVar, ColStdDev : DblDyneVec;
varcovmat, vcmat, workmat : DblDyneMat;
title : string;
begin
errorfound := false;
NoSelected := SelList.Items.Count;
SetLength(Selected,NoSelected);
SetLength(ColLabels,NoSelected);
SetLength(ColMeans,NoSelected);
SetLength(ColVar,NoSelected);
SetLength(RowMeans,NoCases);
SetLength(RowVar,NoCases);
for i := 0 to NoSelected - 1 do
begin
LabelStr := SelList.Items.Strings[i];
for j := 1 to NoVariables do
begin
if LabelStr = OS3MainFrm.DataGrid.Cells[j,0] then
begin
Selected[i] := j;
break;
end;
end;
end;
for i := 1 to NoSelected do
begin
j := Selected[i-1];
ColLabels[i-1] := OS3MainFrm.DataGrid.Cells[j,0];
end;
// Initialize values
SScols := 0.0;
SSrows := 0.0;
SStot := 0.0;
dfwrows := 0.0;
dftot := 0.0;
GrandMean := 0.0;
count := 0;
for i := 0 to NoSelected-1 do
begin
ColMeans[i] := 0.0;
ColVar[i] := 0.0;
end;
for j := 0 to NoCases-1 do
begin
RowMeans[j] := 0.0;
RowVar[j] := 0.0;
end;
// Read data and compute sums while reading
row := 0;
for i := 1 to NoCases do
begin
if NOT GoodRecord(i,NoSelected,Selected) then continue;
count := count + 1;
for j := 1 to NoSelected do
begin
k := Selected[j-1];
X := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[k,i]));
RowMeans[row] := RowMeans[row] + X;
RowVar[row] := RowVar[row] + (X * X);
ColMeans[j-1] := ColMeans[j-1] + X;
ColVar[j-1] := ColVar[j-1] + (X * X);
GrandMean := GrandMean + X;
SStot := SStot + (X * X);
end;
row := row + 1;
end;
// Calculate ANOVA results
Term1 := (GrandMean * GrandMean) / (count * NoSelected);
Term2 := SStot;
for i := 1 to count do SSrows := SSrows + (RowMeans[i-1] * RowMeans[i-1]);
Term4 := SSrows / NoSelected;
for i := 1 to NoSelected do SScols := SScols + (ColMeans[i-1] * ColMeans[i-1]);
Term3 := SScols / count;
SSrows := Term4 - Term1;
SScols := Term3 - Term1;
SSwrows := Term2 - Term4;
SSerr := Term2 - Term3 - Term4 + Term1;
SStot := Term2 - Term1;
dfrows := count - 1;
dfcols := NoSelected - 1;
dfwrows := count * (NoSelected - 1);
dferr := (count - 1) * (NoSelected - 1);
dftot := (count * NoSelected) - 1;
MSrows := SSrows / dfrows;
MScols := SScols / dfcols;
MSwrows := SSwrows / dfwrows;
MSerr := SSerr / dferr;
MStot := SStot / dftot; // variance of all scores
GrandMean := GrandMean / (count * NoSelected);
for i := 0 to count-1 do
begin
RowVar[i] := RowVar[i] - (RowMeans[i] * RowMeans[i] / NoSelected);
RowVar[i] := RowVar[i] / (NoSelected - 1);
RowMeans[i] := RowMeans[i] / NoSelected;
end;
for i := 0 to NoSelected-1 do
begin
ColVar[i] := ColVar[i] - (ColMeans[i] * ColMeans[i] / count);
ColVar[i] := ColVar[i] / (count - 1);
ColMeans[i] := ColMeans[i] / count;
end;
f1 := MScols / MSerr; // treatment F statistic
probf1 := probf(f1,dfcols,dferr);
// Do reliability terms if requested
if RelChk.Checked then
begin
r1 := 1.0 - (MSwrows / MSrows); // unadjusted reliability of test
r2 := (MSrows - MSwrows) / (MSrows + (NoSelected - 1) * MSwrows);
// r2 is unadjusted reliability of a single item
r3 := (MSrows - MSerr) / MSrows; // Cronbach alpha for test
r4 := (MSrows - MSerr) / (MSrows + (NoSelected - 1) * MSerr);
// r4 is adjusted reliability of a single item
end;
// do homogeneity of variance and covariance checks if requested
// print results
OutPutFrm.RichEdit.Clear;
OutPutFrm.RichEdit.Lines.Add('Treatments by Subjects (AxS) ANOVA Results.');
OutPutFrm.RichEdit.Lines.Add('');
outline := 'Data File = ' + OS3MainFrm.FileNameEdit.Text;
OutPutFrm.RichEdit.Lines.Add(outline);
OutPutFrm.RichEdit.Lines.Add('');
OutPutFrm.RichEdit.Lines.Add('');
OutPutFrm.RichEdit.Lines.Add('-----------------------------------------------------------');
OutPutFrm.RichEdit.Lines.Add('SOURCE DF SS MS F Prob. > F');
OutPutFrm.RichEdit.Lines.Add('-----------------------------------------------------------');
outline := format('SUBJECTS %4.0f%10.3f%10.3f',[dfrows,SSrows,MSrows]);
OutPutFrm.RichEdit.Lines.Add(outline);
outline := format('WITHIN SUBJECTS%4.0f%10.3f%10.3f',[dfwrows,SSwrows,MSwrows]);
OutPutFrm.RichEdit.Lines.Add(outline);
outline := format(' TREATMENTS %4.0f%10.3f%10.3f%10.3f%10.3f',[dfcols,SScols,MScols,f1,probf1]);
OutPutFrm.RichEdit.Lines.Add(outline);
outline := format(' RESIDUAL %4.0f%10.3f%10.3f',[dferr,SSerr,MSerr]);
OutPutFrm.RichEdit.Lines.Add(outline);
OutPutFrm.RichEdit.Lines.Add('-----------------------------------------------------------');
outline := format('TOTAL %4.0f%10.3f%10.3f',[dftot,SStot,MStot]);
OutPutFrm.RichEdit.Lines.Add(outline);
OutPutFrm.RichEdit.Lines.Add('-----------------------------------------------------------');
OutPutFrm.RichEdit.Lines.Add('');
OutPutFrm.RichEdit.Lines.Add('');
OutPutFrm.RichEdit.Lines.Add('TREATMENT (COLUMN) MEANS AND STANDARD DEVIATIONS');
OutPutFrm.RichEdit.Lines.Add('VARIABLE MEAN STD.DEV.');
for i := 1 to NoSelected do
begin
outline := format('%-8s%10.3f%10.3f',[ColLabels[i-1],ColMeans[i-1],sqrt(ColVar[i-1])]);
OutPutFrm.RichEdit.Lines.Add(outline);
end;
OutPutFrm.RichEdit.Lines.Add('');
outline := format('Mean of all scores = %10.3f with standard deviation = %10.3f',
[GrandMean, sqrt(MStot)]);
OutPutFrm.RichEdit.Lines.Add(outline);
OutPutFrm.RichEdit.Lines.Add('');
// Do reliability estimates if requested
if RelChk.Checked then
begin
OutPutFrm.RichEdit.Lines.Add('RELIABILITY ESTIMATES');
OutPutFrm.RichEdit.Lines.Add('');
OutPutFrm.RichEdit.Lines.Add('TYPE OF ESTIMATE VALUE');
outline := format('Unadjusted total reliability %7.3f',[r1]);
OutPutFrm.RichEdit.Lines.Add(outline);
outline := format('Unadjusted item reliability %7.3f',[r2]);
OutPutFrm.RichEdit.Lines.Add(outline);
outline := format('Adjusted total (Cronbach) %7.3f',[r3]);
OutPutFrm.RichEdit.Lines.Add(outline);
outline := format('Adjusted item reliability %7.3f',[r4]);
OutPutFrm.RichEdit.Lines.Add(outline);
OutPutFrm.RichEdit.Lines.Add('');
end;
// Test assumptions of variance - covariance homogeneity if requested
if AssumpChk.Checked then
begin
SetLength(varcovmat,NoSelected+1,NoSelected+1);
SetLength(vcmat,NoSelected+1,NoSelected+1);
SetLength(workmat,NoSelected+1,NoSelected+1);
SetLength(ColStdDev,NoSelected);
errorfound := false;
count := NoCases;
OutPutFrm.RichEdit.Lines.Add('BOX TEST FOR HOMOGENEITY OF VARIANCE-COVARIANCE MATRIX');
OutPutFrm.RichEdit.Lines.Add('');
GridCovar(NoSelected,Selected,varcovmat,ColMeans,ColVar,ColStdDev,errorfound,count);
title := 'SAMPLE COVARIANCE MATRIX';
MAT_PRINT(varcovmat,NoSelected,NoSelected,title, ColLabels, ColLabels,NoCases);
if errorfound then
ShowMessage('ERROR! Zero variance found for a variable.');
// get average of variances into workmat diagonal and average of
// covariances into workmat off-diagonals (See Winer, pg 371)
avgvar := 0.0;
avgcov := 0.0;
for i := 0 to NoSelected-1 do vcmat[i,i] := varcovmat[i,i];
for i := 0 to NoSelected-2 do
begin
for j := i+1 to NoSelected-1 do
begin
vcmat[i,j] := varcovmat[i,j];
vcmat[j,i] := vcmat[i,j];
end;
end;
for i := 0 to NoSelected-1 do avgvar := avgvar + varcovmat[i,i];
for i := 0 to NoSelected-2 do
for j := i+1 to NoSelected-1 do avgcov := avgcov + varcovmat[i,j];
avgvar := avgvar / NoSelected;
avgcov := avgcov / (NoSelected * NoSelected - 1) / 2.0;
for i := 0 to NoSelected-1 do workmat[i,i] := avgvar;
for i := 0 to NoSelected-2 do
begin
for j := i+1 to NoSelected-1 do
begin
workmat[i,j] := avgcov;
workmat[j,i] := workmat[i,j];
end;
end;
// get determinants of varcov and workmat
determ1 := 0.0;
determ2 := 0.0;
M2 := 0.0;
C2 := 0.0;
chi2 := 0.0;
f2 := 0;
prob := 0.0;
Determ(vcmat,NoSelected,NoSelected,determ1,errorfound);
if determ1 < 0.0 then determ1 := 0.0;
Determ(workmat,NoSelected,NoSelected,determ2,errorfound);
if determ2 < 0.0 then determ2 := 0.0;
count := NoCases;
GridCovar(NoSelected,Selected,varcovmat,ColMeans,ColVar,ColStdDev,errorfound,count);
errorfound := false;
if ((determ1 > 0.0) and (determ2 > 0.0)) then
M2 := -(NoCases*NoSelected - 1) * ln(determ1 / determ2)
else
begin
M2 := 0.0;
errorfound := true;
ShowMessage('ERROR! A determinant <= zero was found.');
end;
if not errorfound then
begin
C2 := NoSelected * (NoSelected+1) * (NoSelected + 1) * (2 * NoSelected - 3);
C2 := C2 / (6 * (count - 1)*(NoSelected - 1) * (NoSelected * NoSelected + NoSelected - 4));
chi2 := (1.0 - C2) * M2;
f3 := (NoSelected * NoSelected + NoSelected - 4) div 2;
if ((chi2 > 0.01) and (chi2 < 1000.0)) then
prob := chisquaredprob(chi2,f3)
else
begin
if chi2 <= 0.0 then prob := 1.0;
if chi2 >= 1000.0 then prob := 0.0;
end;
end;
title := 'ASSUMED POP. COVARIANCE MATRIX';
for i := 0 to NoSelected-1 do
for j := 0 to NoSelected-1 do
varcovmat[i,j] := workmat[i,j];
MAT_PRINT(varcovmat,NoSelected,NoSelected,title, ColLabels, ColLabels,NoCases);
outline := format('Determinant of variance-covariance matrix = %10.3g',[determ1]);
OutPutFrm.RichEdit.Lines.Add(outline);
outline := format('Determinant of homogeneity matrix = %10.3g',[determ2]);
OutPutFrm.RichEdit.Lines.Add(outline);
if errorfound = false then
begin
outline := format('ChiSquare = %10.3f with %3d degrees of freedom',[chi2,f3]);
OutPutFrm.RichEdit.Lines.Add(outline);
outline := format('Probability of larger chisquare = %6.3g',[1.0-prob]);
OutPutFrm.RichEdit.Lines.Add(outline);
end;
// deallocate heap
ColStdDev := nil;
workmat := nil;
vcmat := nil;
varcovmat := nil;
end;
OutPutFrm.ShowModal;
{ Now, plot values if indicated in options list }
if PlotChk.Checked then
begin
SetLength(GraphFrm.Xpoints,1,NoSelected);
SetLength(GraphFrm.Ypoints,1,NoSelected);
// use rowvar to hold variable no.
for i := 1 to NoSelected do
begin
rowvar[i-1] := Selected[i-1];
GraphFrm.Xpoints[0,i-1] := Selected[i-1];
GraphFrm.Ypoints[0,i-1] := ColMeans[i-1];
end;
GraphFrm.nosets := 1;
GraphFrm.nbars := NoSelected;
GraphFrm.Heading := 'WITHIN SUBJECTS ANOVA';
GraphFrm.XTitle := 'Repeated Measure Var. No.';
GraphFrm.YTitle := 'Mean';
GraphFrm.barwideprop := 0.5;
GraphFrm.AutoScale := true;
GraphFrm.GraphType := 2; // 3d Vertical Bar Chart
GraphFrm.BackColor := clYellow;
GraphFrm.WallColor := clBlack;
GraphFrm.FloorColor := clLtGray;
GraphFrm.ShowBackWall := true;
GraphFrm.ShowModal;
end;
// deallocate space on the heap used for variables
RowVar := nil;
RowMeans := nil;
ColVar := nil;
ColMeans := nil;
ColLabels := nil;
GraphFrm.Xpoints := nil;
GraphFrm.Ypoints := nil;
Selected := nil;
end;
procedure TWithinANOVAFrm.InBtnClick(Sender: TObject);
VAR i, index : integer;
begin
index := VarList.Items.Count;
i := 0;
while i < index do
begin
if (VarList.Selected[i]) then
begin
SelList.Items.Add(VarList.Items.Strings[i]);
VarList.Items.Delete(i);
index := index - 1;
i := 0;
end
else i := i + 1;
end;
OutBtn.Visible := true;
end;
procedure TWithinANOVAFrm.OutBtnClick(Sender: TObject);
VAR index : integer;
begin
index := SelList.ItemIndex;
if index < 0 then
begin
OutBtn.Visible := false;
exit;
end;
VarList.Items.Add(SelList.Items.Strings[index]);
SelList.Items.Delete(index);
end;
initialization
{$I withinanovaunit.lrs}
end.