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
ClientWidth = 420
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 proportions recorded in the data grid for row and column variables'
)
@ -391,4 +391,30 @@ inherited ChiSqrFrm: TChiSqrFrm
Left = 436
Height = 503
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

View File

@ -6,9 +6,9 @@ interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
ExtCtrls, StdCtrls, Buttons,
ExtCtrls, StdCtrls, Buttons, ComCtrls,
MainUnit, FunctionsLib, GraphLib, Globals, MatrixLib, DataProcs,
DictionaryUnit, BasicStatsReportFormUnit;
DictionaryUnit, ReportFrameUnit, BasicStatsReportFormUnit;
type
@ -17,10 +17,15 @@ type
TChiSqrFrm = class(TBasicStatsReportForm)
ObsChk: TCheckBox;
ExpChk: TCheckBox;
PageControl: TPageControl;
PropsChk: TCheckBox;
CellChiChk: TCheckBox;
SaveFChk: TCheckBox;
OptionsGroup: TGroupBox;
ResultsPage: TTabSheet;
FrequenciesPage: TTabSheet;
RowColPage: TTabSheet;
CellChiSqrPage: TTabSheet;
YatesChk: TCheckBox;
RowIn: TBitBtn;
RowOut: TBitBtn;
@ -48,8 +53,12 @@ type
procedure RowOutClick(Sender: TObject);
procedure VarListDblClick(Sender: TObject);
procedure VarListSelectionChange(Sender: TObject; User: boolean);
private
FFrequenciesReportFrame: TReportFrame;
FRowColPropsReportFrame: TReportFrame;
FCellChiSqrReportFrame: TReportFrame;
protected
procedure AdjustConstraints; override;
procedure Compute; override;
@ -69,7 +78,8 @@ implementation
{$R *.lfm}
uses
Math;
Math,
Utils, GridProcs;
{ TChiSqrFrm }
@ -78,8 +88,48 @@ begin
inherited;
if DictionaryFrm = nil then
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;
procedure TChiSqrFrm.AdjustConstraints;
begin
inherited;
@ -127,347 +177,391 @@ var
Prop: DblDyneMat = nil;
Expected: DblDyneMat = nil;
CellChi: DblDyneMat = nil;
RowLabels: StrDyneVec = nil;
ColLabels: StrDyneVec = nil;
yates : boolean = false;
i, j, RowNo, ColNo, DepNo, MinRow, MaxRow, MinCol, MaxCol : integer;
Row, Col, NoSelected, Ncases, Nrows, Ncols, FObs, df : integer;
RowLabels, ColLabels : StrDyneVec;
cellstring: string;
PObs, ChiSquare, ProbChi, phi, SumX, SumY, VarX, VarY, liklihood : double;
yates : boolean;
NoSelected, NCases, NRows, NCols: Integer;
i, j, RowNo, ColNo, DepNo, MinRow, MaxRow, MinCol, MaxCol: integer;
Row, Col, FObs, df: integer;
PObs, ChiSquare, ProbChi, phi, SumX, SumY, VarX, VarY, likelihood: double;
title : string;
Adjchisqr, probliklihood, G, pearsonr, MantelHaenszel, MHprob : double;
Adjprobchi, CoefCont, CramerV : double;
AdjChiSqr, AdjProbChi, probLikelihood, G, pearsonr, MantelHaenszel, MHprob: double;
CoefCont, CramerV: double;
lReport: TStrings;
begin
SetLength(ColNoSelected, NoVariables);
yates := false;
RowNo := 0;
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;
RowNo := GetVariableIndex(OS3MainFrm.DataGrid, RowEdit.Text);
ColNo := GetVariableIndex(OS3MainFrm.DataGrid, ColEdit.Text);
DepNo := GetVariableIndex(OS3MainFrm.DataGrid, DepEdit.Text);
// allocate and initialize
SetLength(Freq,Nrows+1,Ncols+1);
SetLength(Prop,Nrows+1,Ncols+1);
SetLength(Expected,Nrows,Ncols);
SetLength(CellChi,Nrows,Ncols);
SetLength(RowLabels,Nrows+1);
SetLength(ColLabels,Ncols+1);
for i := 1 to Nrows + 1 do
for j := 1 to Ncols + 1 do Freq[i-1,j-1] := 0;
SetLength(ColNoSelected, NoVariables);
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;
SetLength(ColNoSelected, NoSelected);
// get cell data
NCases := 0;
case InputGrp.ItemIndex of
0 : begin // count number of cases in each row and column combination
for i := 1 to NoCases do
begin
if not GoodRecord(i,NoSelected,ColNoSelected) then continue;
NCases := NCases + 1;
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;
Freq[Row-1,Col-1] := Freq[Row-1,Col-1] + 1;
end;
end;
1 : begin // read frequencies data from grid
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;
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;
// Get min and max of row and col numbers
MinRow := MaxInt;
MaxRow := -MinRow;
MinCol := MaxInt;
MaxCol := -MinCol;
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])));
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;
// Now, calculate expected values
// Get row totals first
for i := 1 to Nrows do
for j := 1 to Ncols do
Freq[i-1,Ncols] := Freq[i-1,Ncols] + Freq[i-1,j-1];
// 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
// allocate and initialize
SetLength(Freq, NRows+1, NCols+1);
SetLength(Prop, NRows+1, NCols+1);
SetLength(Expected, NRows, NCols);
SetLength(CellChi, NRows, NCols);
SetLength(RowLabels, NRows+1);
SetLength(ColLabels, NCols+1);
for i := 1 to NRows + 1 do
for j := 1 to NCols + 1 do Freq[i-1, j-1] := 0;
// get cell data
NCases := 0;
case InputGrp.ItemIndex of
0 : begin // count number of cases in each row and column combination
for i := 1 to NoCases 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
MessageDlg('Zero expected value found.', mtError, [mbOK], 0);
CellChi[i-1,j-1] := 0.0;
end;
ChiSquare := ChiSquare + CellChi[i-1,j-1];
if not GoodRecord(OS3MainFrm.DataGrid, i, ColNoSelected) then continue;
NCases := NCases + 1;
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;
Freq[Row-1, Col-1] := Freq[Row-1, Col-1] + 1;
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;
df := (Nrows - 1) * (Ncols - 1);
if yates = true 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
end; // end case
Freq[Nrows, Ncols] := NCases;
// Calculate expected values
// Get row totals first
for i := 1 to NRows do
for j := 1 to Ncols do
Freq[i-1, NCols] := Freq[i-1, NCols] + Freq[i-1, j-1];
// 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');
// 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
begin
IntArrayPrint(Freq, Nrows+1, Ncols+1,'Rows',
RowLabels, ColLabels,'OBSERVED FREQUENCIES', lReport);
lReport.Add('------------------------------------------------------------------------------');
IntArrayPrint(Freq, NRows+1, NCols+1, 'Rows', RowLabels, ColLabels, 'OBSERVED FREQUENCIES', lReport);
lReport.Add(DIVIDER_SMALL_AUTO);
lReport.Add('');
end;
if ExpChk.Checked then
begin
title := 'EXPECTED FREQUENCIES';
MatPrint(Expected,Nrows,Ncols,title,RowLabels,ColLabels,NCases, lReport);
lReport.Add('------------------------------------------------------------------------------');
lReport.Add('');
MatPrint(Expected, NRows, NCols, title, RowLabels, ColLabels, NCases, lReport);
end;
FFrequenciesReportFrame.DisplayReport(lReport);
lReport.Clear;
end else
FrequenciesPage.TabVisible := false;
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
if PropsChk.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 := '';
RowColPage.TabVisible := true;
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;
lReport.Add('CHI-SQUARE ANALYSIS RESULTS');
lReport.Add('');
MatPrint(Prop, NRows+1, NCols+1, title, RowLabels, ColLabels, NCases, lReport);
// 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);
lReport.Add(DIVIDER_SMALL_AUTO);
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(DIVIDER_SMALL_AUTO);
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(DIVIDER_SMALL_AUTO);
lReport.Add('');
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;
//clean up
ColLabels := nil;
RowLabels := nil;
CellChi := nil;
Expected := nil;
Prop := nil;
Freq := nil;
ColNoSelected := nil;
likelihood := 0.0;
for i := 0 to NRows-1 do
for j := 0 to NCols-1 do
if (Freq[i, j] > 0.0) then
likelihood := Likelihood + (Freq[i, j] * (ln(Expected[i, j] / Freq[i,j ])));
likelihood := -2.0 * likelihood;
probLikelihood := 1.0 - ChiSquaredProb(likelihood, df);
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;
@ -548,6 +642,10 @@ begin
CellChiChk.Checked := false;
SaveFChk.Checked := false;
FrequenciesPage.TabVisible := false;
RowColPage.TabVisible := false;
CellChiSqrPage.TabVisible := false;
UpdateBtnStates;
end;

View File

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

View File

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