LazStats: Add pagecontrol tabs to ChiSqrUnits for partial reports.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7804 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2020-10-25 21:41:09 +00:00
parent f60e4c0a67
commit bd9d5086b8
4 changed files with 445 additions and 320 deletions

View File

@ -61,7 +61,7 @@ inherited ChiSqrFrm: TChiSqrFrm
ClientHeight = 69 ClientHeight = 69
ClientWidth = 420 ClientWidth = 420
Items.Strings = ( Items.Strings = (
'Count vases classified by row and column vectors in the data grid' 'Count cases classified by row and column vectors in the data grid'
'Use frequencies recorded in the data grid for row and column variables' 'Use frequencies recorded in the data grid for row and column variables'
'Use proportions recorded in the data grid for row and column variables' 'Use proportions recorded in the data grid for row and column variables'
) )
@ -391,4 +391,30 @@ inherited ChiSqrFrm: TChiSqrFrm
Left = 436 Left = 436
Height = 503 Height = 503
end end
object PageControl: TPageControl[2]
Left = 445
Height = 487
Top = 8
Width = 561
ActivePage = ResultsPage
Align = alClient
BorderSpacing.Left = 4
BorderSpacing.Top = 8
BorderSpacing.Right = 8
BorderSpacing.Bottom = 8
TabIndex = 0
TabOrder = 2
object ResultsPage: TTabSheet
Caption = 'Results'
end
object FrequenciesPage: TTabSheet
Caption = 'Frequencies'
end
object RowColPage: TTabSheet
Caption = 'Row/Column Proportions'
end
object CellChiSqrPage: TTabSheet
Caption = 'Cell ChiSqr'
end
end
end end

View File

@ -6,9 +6,9 @@ interface
uses uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
ExtCtrls, StdCtrls, Buttons, ExtCtrls, StdCtrls, Buttons, ComCtrls,
MainUnit, FunctionsLib, GraphLib, Globals, MatrixLib, DataProcs, MainUnit, FunctionsLib, GraphLib, Globals, MatrixLib, DataProcs,
DictionaryUnit, BasicStatsReportFormUnit; DictionaryUnit, ReportFrameUnit, BasicStatsReportFormUnit;
type type
@ -17,10 +17,15 @@ type
TChiSqrFrm = class(TBasicStatsReportForm) TChiSqrFrm = class(TBasicStatsReportForm)
ObsChk: TCheckBox; ObsChk: TCheckBox;
ExpChk: TCheckBox; ExpChk: TCheckBox;
PageControl: TPageControl;
PropsChk: TCheckBox; PropsChk: TCheckBox;
CellChiChk: TCheckBox; CellChiChk: TCheckBox;
SaveFChk: TCheckBox; SaveFChk: TCheckBox;
OptionsGroup: TGroupBox; OptionsGroup: TGroupBox;
ResultsPage: TTabSheet;
FrequenciesPage: TTabSheet;
RowColPage: TTabSheet;
CellChiSqrPage: TTabSheet;
YatesChk: TCheckBox; YatesChk: TCheckBox;
RowIn: TBitBtn; RowIn: TBitBtn;
RowOut: TBitBtn; RowOut: TBitBtn;
@ -48,8 +53,12 @@ type
procedure RowOutClick(Sender: TObject); procedure RowOutClick(Sender: TObject);
procedure VarListDblClick(Sender: TObject); procedure VarListDblClick(Sender: TObject);
procedure VarListSelectionChange(Sender: TObject; User: boolean); procedure VarListSelectionChange(Sender: TObject; User: boolean);
private private
FFrequenciesReportFrame: TReportFrame;
FRowColPropsReportFrame: TReportFrame;
FCellChiSqrReportFrame: TReportFrame;
protected protected
procedure AdjustConstraints; override; procedure AdjustConstraints; override;
procedure Compute; override; procedure Compute; override;
@ -69,7 +78,8 @@ implementation
{$R *.lfm} {$R *.lfm}
uses uses
Math; Math,
Utils, GridProcs;
{ TChiSqrFrm } { TChiSqrFrm }
@ -78,8 +88,48 @@ begin
inherited; inherited;
if DictionaryFrm = nil then if DictionaryFrm = nil then
Application.CreateForm(TDictionaryFrm, DictionaryFrm); Application.CreateForm(TDictionaryFrm, DictionaryFrm);
FReportFrame.Parent := ResultsPage;
FReportFrame.BorderSpacing.Left := 0;
FReportFrame.BorderSpacing.Top := 0;
FReportFrame.BorderSpacing.Bottom := 0;
FReportFrame.BorderSpacing.Right := 0;
InitToolbar(FReportFrame.ReportToolbar, tpRight);
FFrequenciesReportFrame := TReportFrame.Create(self);
FFrequenciesReportFrame.Name := '';
FFrequenciesReportFrame.Parent := FrequenciesPage;
FFrequenciesReportFrame.Align := alClient;
FFrequenciesReportFrame.BorderSpacing.Left := 0;
FFrequenciesReportFrame.BorderSpacing.Top := 0;
FFrequenciesReportFrame.BorderSpacing.Bottom := 0;
FFrequenciesReportFrame.BorderSpacing.Right := 0;
InitToolbar(FFrequenciesReportFrame.ReportToolbar, tpRight);
FRowColPropsReportFrame := TReportFrame.Create(self);
FRowColPropsReportFrame.Name := '';
FRowColPropsReportFrame.Parent := RowColPage;
FRowColPropsReportFrame.Align := alClient;
FRowColPropsReportFrame.BorderSpacing.Left := 0;
FRowColPropsReportFrame.BorderSpacing.Top := 0;
FRowColPropsReportFrame.BorderSpacing.Bottom := 0;
FRowColPropsReportFrame.BorderSpacing.Right := 0;
InitToolbar(FRowColPropsReportFrame.ReportToolbar, tpRight);
FCellChiSqrReportFrame := TReportFrame.Create(self);
FCellChiSqrReportFrame.Name := '';
FCellChiSqrReportFrame.Parent := CellChiSqrPage;
FCellChiSqrReportFrame.Align := alClient;
FCellChiSqrReportFrame.BorderSpacing.Left := 0;
FCellChiSqrReportFrame.BorderSpacing.Top := 0;
FCellChiSqrReportFrame.BorderSpacing.Bottom := 0;
FCellChiSqrReportFrame.BorderSpacing.Right := 0;
InitToolbar(FCellChiSqrReportFrame.ReportToolbar, tpRight);
PageControl.ActivePageIndex := 0;
end; end;
procedure TChiSqrFrm.AdjustConstraints; procedure TChiSqrFrm.AdjustConstraints;
begin begin
inherited; inherited;
@ -127,347 +177,391 @@ var
Prop: DblDyneMat = nil; Prop: DblDyneMat = nil;
Expected: DblDyneMat = nil; Expected: DblDyneMat = nil;
CellChi: DblDyneMat = nil; CellChi: DblDyneMat = nil;
RowLabels: StrDyneVec = nil;
ColLabels: StrDyneVec = nil;
yates : boolean = false;
i, j, RowNo, ColNo, DepNo, MinRow, MaxRow, MinCol, MaxCol : integer; NoSelected, NCases, NRows, NCols: Integer;
Row, Col, NoSelected, Ncases, Nrows, Ncols, FObs, df : integer; i, j, RowNo, ColNo, DepNo, MinRow, MaxRow, MinCol, MaxCol: integer;
RowLabels, ColLabels : StrDyneVec; Row, Col, FObs, df: integer;
cellstring: string; PObs, ChiSquare, ProbChi, phi, SumX, SumY, VarX, VarY, likelihood: double;
PObs, ChiSquare, ProbChi, phi, SumX, SumY, VarX, VarY, liklihood : double;
yates : boolean;
title : string; title : string;
Adjchisqr, probliklihood, G, pearsonr, MantelHaenszel, MHprob : double; AdjChiSqr, AdjProbChi, probLikelihood, G, pearsonr, MantelHaenszel, MHprob: double;
Adjprobchi, CoefCont, CramerV : double; CoefCont, CramerV: double;
lReport: TStrings; lReport: TStrings;
begin begin
SetLength(ColNoSelected, NoVariables); RowNo := GetVariableIndex(OS3MainFrm.DataGrid, RowEdit.Text);
yates := false; ColNo := GetVariableIndex(OS3MainFrm.DataGrid, ColEdit.Text);
RowNo := 0; DepNo := GetVariableIndex(OS3MainFrm.DataGrid, DepEdit.Text);
ColNo := 0;
DepNo := 0;
for i := 1 to NoVariables do
begin
cellstring := OS3MainFrm.DataGrid.Cells[i,0];
if cellstring = RowEdit.Text then RowNo := i;
if cellstring = ColEdit.Text then ColNo := i;
if cellstring = DepEdit.Text then DepNo := i;
end;
ColNoSelected[0] := RowNo;
ColNoSelected[1] := ColNo;
NoSelected := 2;
if InputGrp.ItemIndex > 0 then // for reading proportions or frequencies
begin
NoSelected := 3;
ColNoSelected[2] := DepNo;
end;
// get min and max of row and col numbers
MinRow := 1000;
MaxRow := 0;
MinCol := 1000;
MaxCol := 0;
for i := 1 to NoCases do
begin
if not GoodRecord(i,NoSelected,ColNoSelected) then continue;
Row := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[RowNo,i])));
Col := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[ColNo,i])));
if Row > MaxRow then MaxRow := Row;
if Row < MinRow then MinRow := Row;
if Col > MaxCol then MaxCol := Col;
if Col < MinCol then MinCol := Col;
end;
Nrows := MaxRow - MinRow + 1;
Ncols := MaxCol - MinCol + 1;
// allocate and initialize SetLength(ColNoSelected, NoVariables);
SetLength(Freq,Nrows+1,Ncols+1); ColNoSelected[0] := RowNo;
SetLength(Prop,Nrows+1,Ncols+1); ColNoSelected[1] := ColNo;
SetLength(Expected,Nrows,Ncols); NoSelected := 2;
SetLength(CellChi,Nrows,Ncols); if InputGrp.ItemIndex > 0 then // for reading proportions or frequencies
SetLength(RowLabels,Nrows+1); begin
SetLength(ColLabels,Ncols+1); NoSelected := 3;
for i := 1 to Nrows + 1 do ColNoSelected[2] := DepNo;
for j := 1 to Ncols + 1 do Freq[i-1,j-1] := 0; end;
SetLength(ColNoSelected, NoSelected);
// get cell data // Get min and max of row and col numbers
NCases := 0; MinRow := MaxInt;
case InputGrp.ItemIndex of MaxRow := -MinRow;
0 : begin // count number of cases in each row and column combination MinCol := MaxInt;
for i := 1 to NoCases do MaxCol := -MinCol;
begin for i := 1 to NoCases do
if not GoodRecord(i,NoSelected,ColNoSelected) then continue; begin
NCases := NCases + 1; if not GoodRecord(OS3MainFrm.DataGrid, i, ColNoSelected) then continue;
Row := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[RowNo,i]))); Row := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[RowNo, i])));
Col := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[ColNo,i]))); Col := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[ColNo, i])));
Row := Row - MinRow + 1; if Row > MaxRow then MaxRow := Row;
Col := Col - MinCol + 1; if Row < MinRow then MinRow := Row;
Freq[Row-1,Col-1] := Freq[Row-1,Col-1] + 1; if Col > MaxCol then MaxCol := Col;
end; if Col < MinCol then MinCol := Col;
end; end;
1 : begin // read frequencies data from grid NRows := MaxRow - MinRow + 1;
for i := 1 to NoCases do NCols := MaxCol - MinCol + 1;
begin
if not GoodRecord(i,NoSelected,ColNoSelected) then continue;
Row := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[RowNo,i])));
Col := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[ColNo,i])));
Row := Row - MinRow + 1;
Col := Col - MinCol + 1;
FObs := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[DepNo,i])));
Freq[Row-1,Col-1] := Freq[Row-1,Col-1] + FObs;
NCases := NCases + FObs;
end;
end;
2 : begin // get no. of cases and proportions for each cell
NCases := StrToInt(NCasesEdit.Text);
for i := 1 to NoCases do
begin
if not GoodRecord(i,NoSelected,ColNoSelected) then continue;
Row := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[RowNo,i])));
Col := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[ColNo,i])));
Row := Row - MinRow + 1;
Col := Col - MinCol + 1;
PObs := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[DepNo,i]));
Freq[Row-1,Col-1] := Freq[Row-1,Col-1] + round(PObs * NCases);
end;
end;
end; // end case
Freq[Nrows,Ncols] := NCases;
// Now, calculate expected values // allocate and initialize
// Get row totals first SetLength(Freq, NRows+1, NCols+1);
for i := 1 to Nrows do SetLength(Prop, NRows+1, NCols+1);
for j := 1 to Ncols do SetLength(Expected, NRows, NCols);
Freq[i-1,Ncols] := Freq[i-1,Ncols] + Freq[i-1,j-1]; SetLength(CellChi, NRows, NCols);
// Get col totals next SetLength(RowLabels, NRows+1);
for j := 1 to Ncols do SetLength(ColLabels, NCols+1);
for i := 1 to Nrows do
Freq[Nrows,j-1] := Freq[Nrows,j-1] + Freq[i-1,j-1]; for i := 1 to NRows + 1 do
// Then get expected values and cell chi-squares for j := 1 to NCols + 1 do Freq[i-1, j-1] := 0;
ChiSquare := 0.0;
AdjChisqr := 0.0; // get cell data
if (YatesChk.Checked) and (Nrows = 2) and (Ncols = 2) then yates := true; NCases := 0;
for i := 1 to Nrows do case InputGrp.ItemIndex of
begin 0 : begin // count number of cases in each row and column combination
for j := 1 to Ncols do for i := 1 to NoCases do
begin begin
Expected[i-1,j-1] := Freq[Nrows,j-1] * Freq[i-1,Ncols] / NCases; if not GoodRecord(OS3MainFrm.DataGrid, i, ColNoSelected) then continue;
if Expected[i-1,j-1] > 0.0 then NCases := NCases + 1;
CellChi[i-1,j-1] := sqr(Freq[i-1,j-1] - Expected[i-1,j-1]) / Expected[i-1,j-1] Row := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[RowNo, i])));
else begin Col := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[ColNo, i])));
MessageDlg('Zero expected value found.', mtError, [mbOK], 0); Row := Row - MinRow + 1;
CellChi[i-1,j-1] := 0.0; Col := Col - MinCol + 1;
end; Freq[Row-1, Col-1] := Freq[Row-1, Col-1] + 1;
ChiSquare := ChiSquare + CellChi[i-1,j-1];
end; end;
end;
1 : begin // read frequencies data from grid
for i := 1 to NoCases do
begin
if not GoodRecord(OS3MainFrm.DataGrid, i, ColNoSelected) then continue;
Row := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[RowNo, i])));
Col := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[ColNo, i])));
Row := Row - MinRow + 1;
Col := Col - MinCol + 1;
FObs := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[DepNo, i])));
Freq[Row-1, Col-1] := Freq[Row-1, Col-1] + FObs;
NCases := NCases + FObs;
end;
end;
2 : begin // get no. of cases and proportions for each cell
NCases := StrToInt(NCasesEdit.Text);
for i := 1 to NoCases do
begin
if not GoodRecord(OS3MainFrm.Datagrid, i, ColNoSelected) then continue;
Row := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[RowNo, i])));
Col := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[ColNo, i])));
Row := Row - MinRow + 1;
Col := Col - MinCol + 1;
PObs := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[DepNo, i]));
Freq[Row-1, Col-1] := Freq[Row-1, Col-1] + round(PObs * NCases);
end;
end; end;
df := (Nrows - 1) * (Ncols - 1); end; // end case
if yates = true then // 2 x 2 corrected chi-square Freq[Nrows, Ncols] := NCases;
begin
Adjchisqr := abs((Freq[0,0] * Freq[1,1]) - (Freq[0,1] * Freq[1,0])); // Calculate expected values
Adjchisqr := sqr(Adjchisqr - NCases / 2.0) * NCases; // numerator // Get row totals first
Adjchisqr := Adjchisqr / (Freq[0,2] * Freq[1,2] * Freq[2,0] * Freq[2,1]); for i := 1 to NRows do
Adjprobchi := 1.0 - chisquaredprob(Adjchisqr,df); for j := 1 to Ncols do
end; Freq[i-1, NCols] := Freq[i-1, NCols] + Freq[i-1, j-1];
ProbChi := 1.0 - chisquaredprob(ChiSquare,df); // prob. larger chi
// Get col totals next
for j := 1 to NCols do
for i := 1 to NRows do
Freq[NRows, j-1] := Freq[NRows, j-1] + Freq[i-1, j-1];
// Then get expected values and cell chi-squares
ChiSquare := 0.0;
AdjChisqr := 0.0;
if (YatesChk.Checked) and (NRows = 2) and (NCols = 2) then
yates := true;
for i := 1 to NRows do
begin
for j := 1 to Ncols do
begin
Expected[i-1, j-1] := Freq[NRows, j-1] * Freq[i-1, NCols] / NCases;
if Expected[i-1, j-1] > 0.0 then
CellChi[i-1, j-1] := sqr(Freq[i-1, j-1] - Expected[i-1, j-1]) / Expected[i-1, j-1]
else begin
ErrorMsg('Zero expected value found.');
CellChi[i-1,j-1] := 0.0;
end;
ChiSquare := ChiSquare + CellChi[i-1, j-1];
end;
end;
df := (Nrows - 1) * (Ncols - 1);
if yates then // 2 x 2 corrected chi-square
begin
AdjChiSqr := abs((Freq[0,0] * Freq[1,1]) - (Freq[0,1] * Freq[1,0]));
AdjChiSqr := sqr(AdjChiSqr - NCases / 2.0) * NCases; // numerator
AdjChiSqr := AdjChiSqr / (Freq[0,2] * Freq[1,2] * Freq[2,0] * Freq[2,1]);
AdjProbChi := 1.0 - ChiSquaredProb(AdjChiSqr, df);
end;
ProbChi := 1.0 - ChiSquaredProb(ChiSquare, df); // prob. larger chi
for i := 1 to NRows do RowLabels[i-1] := Format('Row %d', [i]);
RowLabels[NRows] := 'Total';
for j := 1 to NCols do ColLabels[j-1] := Format('Col.%d', [j]);
ColLabels[NCols] := 'Total';
// Print results to output frames
lReport := TStringList.Create;
try
// print frequencies tables requested by user
if ObsChk.Checked or ExpChk.Checked then
begin
FrequenciesPage.TabVisible := true;
//Print results to output form
lReport := TStringList.Create;
try
lReport.Add('CHI-SQUARE ANALYSIS RESULTS'); lReport.Add('CHI-SQUARE ANALYSIS RESULTS');
// print tables requested by use
for i := 1 to Nrows do RowLabels[i-1] := Format('Row %d', [i]);
RowLabels[Nrows] := 'Total';
for j := 1 to Ncols do ColLabels[j-1] := Format('COL.%d', [j]);
ColLabels[Ncols] := 'Total';
if ObsChk.Checked then if ObsChk.Checked then
begin begin
IntArrayPrint(Freq, Nrows+1, Ncols+1,'Rows', IntArrayPrint(Freq, NRows+1, NCols+1, 'Rows', RowLabels, ColLabels, 'OBSERVED FREQUENCIES', lReport);
RowLabels, ColLabels,'OBSERVED FREQUENCIES', lReport); lReport.Add(DIVIDER_SMALL_AUTO);
lReport.Add('------------------------------------------------------------------------------');
lReport.Add(''); lReport.Add('');
end; end;
if ExpChk.Checked then if ExpChk.Checked then
begin begin
title := 'EXPECTED FREQUENCIES'; title := 'EXPECTED FREQUENCIES';
MatPrint(Expected,Nrows,Ncols,title,RowLabels,ColLabels,NCases, lReport); MatPrint(Expected, NRows, NCols, title, RowLabels, ColLabels, NCases, lReport);
lReport.Add('------------------------------------------------------------------------------');
lReport.Add('');
end; end;
FFrequenciesReportFrame.DisplayReport(lReport);
lReport.Clear;
end else
FrequenciesPage.TabVisible := false;
if PropsChk.Checked then if PropsChk.Checked then
begin
title := 'ROW PROPORTIONS';
for i := 1 to Nrows + 1 do
begin
for j := 1 to Ncols do
begin
if Freq[i-1,Ncols] > 0.0 then
Prop[i-1,j-1] := Freq[i-1,j-1] / Freq[i-1,Ncols]
else Prop[i-1,j-1] := 0.0;
end;
if Freq[i-1,Ncols] > 0.0 then Prop[i-1,Ncols] := 1.0
else Prop[i-1,Ncols] := 0.0;
end;
MatPrint(Prop,Nrows+1,Ncols+1,title,RowLabels,ColLabels,NCases, lReport);
lReport.Add('------------------------------------------------------------------------------');
lReport.Add('');
title := 'COLUMN PROPORTIONS';
for j := 1 to Ncols + 1 do
begin
for i := 1 to Nrows do
begin
if Freq[Nrows,j-1] > 0.0 then
Prop[i-1,j-1] := Freq[i-1,j-1] / Freq[Nrows,j-1]
else Prop[i-1,j-1] := 0.0;
end;
if Freq[Nrows,j-1] > 0.0 then Prop[NRows,j-1] := 1.0
else Prop[NRows,j-1] := 0.0;
end;
MatPrint(Prop,Nrows+1,Ncols+1,title,RowLabels,ColLabels,NCases, lReport);
lReport.Add('------------------------------------------------------------------------------');
lReport.Add('');
Title := 'PROPORTIONS OF TOTAL N';
for i := 1 to Nrows + 1 do
for j := 1 to Ncols + 1 do Prop[i-1,j-1] := Freq[i-1,j-1] / NCases;
Prop[Nrows,Ncols] := 1.0;
MatPrint(Prop,Nrows+1,Ncols+1,title,RowLabels,ColLabels,NCases, lReport);
lReport.Add('------------------------------------------------------------------------------');
lReport.Add('');
end;
if CellChiChk.Checked then
begin
title := 'CHI-SQUARED VALUE FOR CELLS';
MatPrint(CellChi,Nrows,Ncols,title,RowLabels,ColLabels,NCases, lReport);
lReport.Add('------------------------------------------------------------------------------');
lReport.Add('');
end;
lReport.Add('Chi-square: %.3f with D.F. = %d. Prob. > value %.3f', [ChiSquare, df, ProbChi]);
lReport.Add('');
if yates then
lReport.Add('Chi-square using Yates correction: %.3f and Prob > value: %.3f', [Adjchisqr, Adjprobchi]);
liklihood := 0.0;
for i := 0 to Nrows-1 do
for j := 0 to Ncols-1 do
if (Freq[i,j] > 0.0) then
liklihood := Liklihood + (Freq[i,j] * (ln(Expected[i,j] / Freq[i,j])));
liklihood := -2.0 * liklihood;
probliklihood := 1.0 - chisquaredprob(liklihood,df);
lReport.Add('Likelihood Ratio: %.3f with prob. > value %.4f', [liklihood, probliklihood]);
G := 0.0;
for i := 0 to Nrows-1 do
for j := 0 to Ncols-1 do
if (Expected[i,j] > 0) then
G := G + Freq[i,j] * (ln(Freq[i,j] / Expected[i,j]));
G := 2.0 * G;
probliklihood := 1.0 - chisquaredprob(G,df);
lReport.Add('G statistic: %.3f with prob. > value %.4f', [G, probliklihood]);
if ((Nrows > 1) and (Ncols > 1)) then
begin
phi := sqrt(ChiSquare / Ncases);
lReport.Add('phi correlation: %.4f', [phi]);
lReport.Add('');
pearsonr := 0.0;
SumX := 0.0;
SumY := 0.0;
VarX := 0.0;
VarY := 0.0;
for i := 0 to Nrows-1 do SumX := SumX + ( (i+1) * Freq[i,Ncols] );
for j := 0 to Ncols-1 do SumY := SumY + ( (j+1) * Freq[Nrows,j] );
for i := 0 to Nrows-1 do VarX := VarX + ( ((i+1)*(i+1)) * Freq[i,Ncols] );
for j := 0 to Ncols-1 do VarY := VarY + ( ((j+1)*(j+1)) * Freq[Nrows,j] );
VarX := VarX - ((SumX * SumX) / Ncases);
VarY := VarY - ((SumY * SumY) / Ncases);
for i := 0 to Nrows-1 do
for j := 0 to Ncols-1 do
pearsonr := pearsonr + ((i+1)*(j+1) * Freq[i,j]);
pearsonr := pearsonr - (SumX * SumY / Ncases);
pearsonr := pearsonr / sqrt(VarX * VarY);
lReport.Add('Pearson Correlation r: %.4f', [pearsonr]);
lReport.Add('');
MantelHaenszel := (Ncases-1) * (pearsonr * pearsonr);
MHprob := 1.0 - chisquaredprob(MantelHaenszel,1);
lReport.Add('Mantel-Haenszel Test of Linear Association: %.3f with probability > value %.4f', [MantelHaenszel, MHprob]);
lReport.Add('');
CoefCont := sqrt(ChiSquare / (ChiSquare + Ncases));
lReport.Add('The coefficient of contingency: %.3f', [CoefCont]);
lReport.Add('');
if (Nrows < Ncols) then
CramerV := sqrt(ChiSquare / (Ncases * ((Nrows-1))))
else
CramerV := sqrt(ChiSquare / (Ncases * ((Ncols-1))));
lReport.Add('Cramers V: %.3f', [CramerV]);
lReport.Add('');
end;
FReportFrame.DisplayReport(lReport);
finally
lReport.Free;
end;
// save frequency data file if elected
if SaveFChk.Checked then
begin begin
OS3MainFrm.mnuFileCloseClick(self); RowColPage.TabVisible := true;
OS3MainFrm.FileNameEdit.Text := ''; title := 'ROW PROPORTIONS';
for i := 1 to DictionaryFrm.DictGrid.RowCount - 1 do for i := 1 to NRows + 1 do
for j := 0 to 7 do DictionaryFrm.DictGrid.Cells[j,i] := ''; begin
DictionaryFrm.DictGrid.RowCount := 1; for j := 1 to NCols do
// DictionaryFrm.FileNameEdit.Text := ''; begin
if Freq[i-1, NCols] > 0.0 then
Prop[i-1, j-1] := Freq[i-1, j-1] / Freq[i-1, NCols]
else
Prop[i-1, j-1] := 0.0;
end;
if Freq[i-1, NCols] > 0.0 then
Prop[i-1, NCols] := 1.0
else
Prop[i-1, NCols] := 0.0;
end;
lReport.Add('CHI-SQUARE ANALYSIS RESULTS');
lReport.Add('');
MatPrint(Prop, NRows+1, NCols+1, title, RowLabels, ColLabels, NCases, lReport);
// get labels for new file lReport.Add(DIVIDER_SMALL_AUTO);
ColLabels[0] := 'ROW'; lReport.Add('');
ColLabels[1] := 'COL';
ColLabels[2] := 'FREQ'; title := 'COLUMN PROPORTIONS';
// create new variables for j := 1 to Ncols + 1 do
Row := 0; begin
OS3MainFrm.DataGrid.ColCount := 4; for i := 1 to Nrows do
DictionaryFrm.DictGrid.ColCount := 8; begin
NoVariables := 0; if Freq[Nrows,j-1] > 0.0 then
for i := 1 to 3 do Prop[i-1,j-1] := Freq[i-1,j-1] / Freq[Nrows,j-1]
begin else
col := NoVariables + 1; Prop[i-1,j-1] := 0.0;
DictionaryFrm.NewVar(col); end;
DictionaryFrm.DictGrid.Cells[1,col] := ColLabels[i-1]; if Freq[Nrows,j-1] > 0.0 then
OS3MainFrm.DataGrid.Cells[col,0] := ColLabels[i-1]; Prop[NRows,j-1] := 1.0
NoVariables := NoVariables + 1; else
end; Prop[NRows,j-1] := 0.0;
OS3MainFrm.DataGrid.RowCount := (Nrows * NCols) + 1; end;
for i := 1 to Nrows do MatPrint(Prop, NRows+1, NCols+1, title, RowLabels, ColLabels, NCases, lReport);
begin
for j := 1 to Ncols do lReport.Add(DIVIDER_SMALL_AUTO);
begin lReport.Add('');
Row := Row + 1;
OS3MainFrm.DataGrid.Cells[0,Row] := Format('Case:%d',[Row]); Title := 'PROPORTIONS OF TOTAL N';
OS3MainFrm.DataGrid.Cells[1,Row] := IntToStr(i); for i := 1 to NRows + 1 do
OS3MainFrm.DataGrid.Cells[2,Row] := IntToStr(j); for j := 1 to NCols + 1 do
OS3MainFrm.DataGrid.Cells[3,Row] := IntToStr(Freq[i-1,j-1]); Prop[i-1,j-1] := Freq[i-1,j-1] / NCases;
end; Prop[Nrows, Ncols] := 1.0;
end; MatPrint(Prop, NRows+1, NCols+1, title, RowLabels, ColLabels, NCases, lReport);
NoCases := Row;
OS3MainFrm.FileNameEdit.Text := 'ChiSqrFreq.LAZ'; lReport.Add(DIVIDER_SMALL_AUTO);
OS3MainFrm.NoCasesEdit.Text := IntToStr(NoCases); lReport.Add('');
OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables);
// OS3MainFrm.SaveFileBtnClick(self); FRowColPropsReportFrame.DisplayReport(lReport);
lReport.Clear;
end else
RowColPage.TabVisible := false;
if CellChiChk.Checked then
begin
CellChiSqrPage.TabVisible := true;
lReport.Add('CHI-SQUARE ANALYSIS RESULTS');
lReport.Add('');
title := 'CHI-SQUARED VALUE FOR CELLS';
MatPrint(CellChi, NRows, NCols, title, RowLabels, ColLabels, NCases, lReport);
FCellChiSqrReportFrame.DisplayReport(lReport);
lReport.Clear;
end else
CellChiSqrPage.TabVisible := false;
lReport.Add('CHI-SQUARE ANALYSIS RESULTS');
lReport.Add('');
lReport.Add('Chi-square: %.3f', [ChiSquare]);
lReport.Add(' with %d degrees of freedom', [DF]);
lReport.Add(' Probability > value is %.4f', [ProbChi]);
lReport.Add('');
if yates then
begin
lReport.Add('Chi-square using Yates correction: %.3f', [AdjChiSqr]);
lReport.Add(' Probability > value is %.4f', [AdjProbChi]);
lReport.Add('');
end; end;
//clean up likelihood := 0.0;
ColLabels := nil; for i := 0 to NRows-1 do
RowLabels := nil; for j := 0 to NCols-1 do
CellChi := nil; if (Freq[i, j] > 0.0) then
Expected := nil; likelihood := Likelihood + (Freq[i, j] * (ln(Expected[i, j] / Freq[i,j ])));
Prop := nil; likelihood := -2.0 * likelihood;
Freq := nil; probLikelihood := 1.0 - ChiSquaredProb(likelihood, df);
ColNoSelected := nil; lReport.Add('Likelihood Ratio: %.3f', [likelihood]);
lReport.Add(' Probability > value is %.4f', [probLikelihood]);
lReport.Add('');
G := 0.0;
for i := 0 to NRows-1 do
for j := 0 to NCols-1 do
if (Expected[i, j] > 0) then
G := G + Freq[i, j] * (ln(Freq[i, j] / Expected[i, j]));
G := 2.0 * G;
probLikelihood := 1.0 - ChiSquaredProb(G, df);
lReport.Add('G statistic: %.3f ', [G]);
lReport.Add(' Probability > value is %.4f', [G, probLikelihood]);
lReport.Add('');
if ((NRows > 1) and (NCols > 1)) then
begin
phi := sqrt(ChiSquare / NCases);
lReport.Add('phi correlation: %.4f', [phi]);
lReport.Add('');
pearsonr := 0.0;
SumX := 0.0;
SumY := 0.0;
VarX := 0.0;
VarY := 0.0;
for i := 0 to NRows-1 do SumX := SumX + ( (i+1) * Freq[i, NCols] );
for j := 0 to NCols-1 do SumY := SumY + ( (j+1) * Freq[NRows, j] );
for i := 0 to NRows-1 do VarX := VarX + ( sqr(i+1) * Freq[i, NCols] );
for j := 0 to NCols-1 do VarY := VarY + ( sqr(j+1) * Freq[NRows, j] );
VarX := VarX - sqr(SumX) / NCases;
VarY := VarY - sqr(SumY) / NCases;
for i := 0 to NRows-1 do
for j := 0 to NCols-1 do
pearsonR := pearsonR + ((i+1)*(j+1) * Freq[i, j]);
pearsonR := pearsonR - (SumX * SumY / Ncases);
pearsonR := pearsonR / sqrt(VarX * VarY);
lReport.Add('Pearson Correlation r: %.4f', [pearsonR]);
lReport.Add('');
MantelHaenszel := (NCases-1) * sqr(pearsonR);
MHprob := 1.0 - ChiSquaredProb(MantelHaenszel, 1);
lReport.Add('Mantel-Haenszel Test of Linear Association: %.3f', [MantelHaenszel]);
lReport.Add(' Probability > value is %.4f', [MantelHaenszel, MHprob]);
lReport.Add('');
CoefCont := sqrt(ChiSquare / (ChiSquare + NCases));
lReport.Add('The coefficient of contingency is %.3f', [CoefCont]);
lReport.Add('');
if (Nrows < Ncols) then
CramerV := sqrt(ChiSquare / (NCases * ((NRows-1))))
else
CramerV := sqrt(ChiSquare / (NCases * ((NCols-1))));
lReport.Add('Cramers V is %.3f', [CramerV]);
lReport.Add('');
end;
FReportFrame.DisplayReport(lReport);
finally
lReport.Free;
end;
// save frequency data file if elected
if SaveFChk.Checked then
begin
OS3MainFrm.mnuFileCloseClick(self);
OS3MainFrm.FileNameEdit.Text := '';
for i := 1 to DictionaryFrm.DictGrid.RowCount - 1 do
for j := 0 to 7 do DictionaryFrm.DictGrid.Cells[j,i] := '';
DictionaryFrm.DictGrid.RowCount := 1;
// DictionaryFrm.FileNameEdit.Text := '';
// get labels for new file
ColLabels[0] := 'ROW';
ColLabels[1] := 'COL';
ColLabels[2] := 'FREQ';
// create new variables
Row := 0;
OS3MainFrm.DataGrid.ColCount := 4;
DictionaryFrm.DictGrid.ColCount := 8;
NoVariables := 0;
for i := 1 to 3 do
begin
col := NoVariables + 1;
DictionaryFrm.NewVar(col);
DictionaryFrm.DictGrid.Cells[1,col] := ColLabels[i-1];
OS3MainFrm.DataGrid.Cells[col,0] := ColLabels[i-1];
NoVariables := NoVariables + 1;
end;
OS3MainFrm.DataGrid.RowCount := (Nrows * NCols) + 1;
for i := 1 to Nrows do
begin
for j := 1 to Ncols do
begin
Row := Row + 1;
OS3MainFrm.DataGrid.Cells[0,Row] := Format('Case:%d',[Row]);
OS3MainFrm.DataGrid.Cells[1,Row] := IntToStr(i);
OS3MainFrm.DataGrid.Cells[2,Row] := IntToStr(j);
OS3MainFrm.DataGrid.Cells[3,Row] := IntToStr(Freq[i-1,j-1]);
end;
end;
NoCases := Row;
OS3MainFrm.FileNameEdit.Text := 'ChiSqrFreq.LAZ';
OS3MainFrm.NoCasesEdit.Text := IntToStr(NoCases);
OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables);
// OS3MainFrm.SaveFileBtnClick(self);
end;
//clean up
ColLabels := nil;
RowLabels := nil;
CellChi := nil;
Expected := nil;
Prop := nil;
Freq := nil;
ColNoSelected := nil;
end; end;
@ -548,6 +642,10 @@ begin
CellChiChk.Checked := false; CellChiChk.Checked := false;
SaveFChk.Checked := false; SaveFChk.Checked := false;
FrequenciesPage.TabVisible := false;
RowColPage.TabVisible := false;
CellChiSqrPage.TabVisible := false;
UpdateBtnStates; UpdateBtnStates;
end; end;

View File

@ -40,6 +40,7 @@ begin
inherited; inherited;
FReportFrame := TReportFrame.Create(self); FReportFrame := TReportFrame.Create(self);
FReportFrame.Name := '';
FReportFrame.Parent := Self; FReportFrame.Parent := Self;
FReportFrame.Align := alClient; FReportFrame.Align := alClient;
FReportFrame.BorderSpacing.Left := 4; FReportFrame.BorderSpacing.Left := 4;

View File

@ -57,8 +57,8 @@ const
constructor TReportFrame.Create(AOwner: TComponent); constructor TReportFrame.Create(AOwner: TComponent);
begin begin
Name := '';
inherited; inherited;
Name := '';
ReportPanel.Color := ReportMemo.Color; ReportPanel.Color := ReportMemo.Color;
UpdateBtnStates; UpdateBtnStates;
end; end;