diff --git a/applications/lazstats/source/forms/analysis/nonparametric/riditunit.lfm b/applications/lazstats/source/forms/analysis/nonparametric/riditunit.lfm index 0613b8a31..5f0ff2eba 100644 --- a/applications/lazstats/source/forms/analysis/nonparametric/riditunit.lfm +++ b/applications/lazstats/source/forms/analysis/nonparametric/riditunit.lfm @@ -1,13 +1,13 @@ inherited RIDITForm: TRIDITForm - Left = 778 + Left = 864 Height = 477 - Top = 182 - Width = 673 + Top = 327 + Width = 903 HelpType = htKeyword HelpKeyword = 'html/RIDITAnalysis.htm' Caption = 'Relative to an Identified Distribution Analysis' ClientHeight = 477 - ClientWidth = 673 + ClientWidth = 903 inherited ParamsPanel: TPanel Height = 461 Width = 416 @@ -408,4 +408,30 @@ inherited RIDITForm: TRIDITForm Left = 428 Height = 477 end + object PageControl: TPageControl[2] + Left = 437 + Height = 461 + Top = 8 + Width = 458 + ActivePage = FrequenciesPage + Align = alClient + BorderSpacing.Left = 4 + BorderSpacing.Top = 8 + BorderSpacing.Right = 8 + BorderSpacing.Bottom = 8 + TabIndex = 1 + TabOrder = 2 + object ResultsPage: TTabSheet + Caption = 'Results' + end + object FrequenciesPage: TTabSheet + Caption = 'Frequencies' + end + object RowColPropsPage: TTabSheet + Caption = 'Row/Column Properties' + end + object CellChiSqrPage: TTabSheet + Caption = 'Cell ChiSsqr' + end + end end diff --git a/applications/lazstats/source/forms/analysis/nonparametric/riditunit.pas b/applications/lazstats/source/forms/analysis/nonparametric/riditunit.pas index 69b845c23..c91290b91 100644 --- a/applications/lazstats/source/forms/analysis/nonparametric/riditunit.pas +++ b/applications/lazstats/source/forms/analysis/nonparametric/riditunit.pas @@ -6,8 +6,8 @@ interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, - StdCtrls, Buttons, ExtCtrls, - MainUnit, Globals, FunctionsLib, MatrixLib, BasicStatsReportFormUnit; + StdCtrls, Buttons, ExtCtrls, ComCtrls, + MainUnit, Globals, FunctionsLib, MatrixLib, ReportFrameUnit, BasicStatsReportFormUnit; type @@ -17,6 +17,7 @@ type Bevel2: TBevel; BonChk: TCheckBox; AlphaEdit: TEdit; + PageControl: TPageControl; Panel1: TPanel; AlphaLabel: TLabel; ObsChk: TCheckBox; @@ -24,6 +25,10 @@ type PropChk: TCheckBox; ChiChk: TCheckBox; RefGrp: TRadioGroup; + ResultsPage: TTabSheet; + FrequenciesPage: TTabSheet; + RowColPropsPage: TTabSheet; + CellChiSqrPage: TTabSheet; YatesChk: TCheckBox; DetailsChk: TCheckBox; ColList: TListBox; @@ -46,15 +51,18 @@ type procedure RefGrpClick(Sender: TObject); procedure RowInClick(Sender: TObject); procedure RowOutClick(Sender: TObject); - procedure Analyze(RefCol: integer; ColNoSelected: IntDyneVec; - RowLabels: StrDyneVec; ColLabels: StrDyneVec; - NoToAnalyze: integer; Freq: IntDyneMat; - Props: DblDyneMat; NoRows: integer; AReport: TStrings); procedure VarListDblClick(Sender: TObject); procedure VarListSelectionChange(Sender: TObject; {%H-}User: boolean); private + FFrequenciesReportFrame: TReportFrame; + FRowColPropsReportFrame: TReportFrame; + FCellChiSqrReportFrame: TReportFrame; + procedure Analyze(RefCol: integer; RowLabels, ColLabels: StrDyneVec; + NoToAnalyze: integer; Freq: IntDyneMat; Props: DblDyneMat; + NoRows: integer; AReport: TStrings); + protected procedure AdjustConstraints; override; procedure Compute; override; @@ -62,6 +70,7 @@ type function Validate(out AMsg: String; out AControl: TWinControl): Boolean; override; public + constructor Create(AOwner: TComponent); override; procedure Reset; override; end; @@ -79,6 +88,46 @@ uses { TRIDITForm } +constructor TRIDITForm.Create(AOwner: TComponent); +begin + inherited; + + FReportFrame.Parent := ResultsPage; + + 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 := RowColPropsPage; + 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 TRIDITForm.AdjustConstraints; begin inherited; @@ -95,11 +144,9 @@ begin end; -procedure TRIDITForm.Analyze(RefCol : integer; ColNoSelected : IntDyneVec; - RowLabels : StrDyneVec; ColLabels : StrDyneVec; - NoToAnalyze : integer; Freq : IntDyneMat; - Props : DblDyneMat; NoRows : integer; - AReport: TStrings); +procedure TRIDITForm.Analyze(RefCol: integer; RowLabels, ColLabels: StrDyneVec; + NoToAnalyze: integer; Freq: IntDyneMat; Props: DblDyneMat; NoRows: integer; + AReport: TStrings); var probdists : DblDyneMat = nil; refprob : DblDyneMat = nil; @@ -218,10 +265,13 @@ begin DynVectorPrint(Cratios, NoToAnalyze, outline, ColLabels, NoCases, AReport); alpha := alpha / 2.0; - if (BonChk.Checked) then alpha := alpha / (NoToAnalyze - 1); - Bonferroni := InverseZ(1.0 - alpha); - AReport.Add('Significance level used for comparisons: %8.3f', [Bonferroni]); - AReport.Add(''); + if BonChk.Checked then + begin + alpha := alpha / (NoToAnalyze - 1); + Bonferroni := InverseZ(1.0 - alpha); + AReport.Add('Significance level used for comparisons: %8.3f', [Bonferroni]); + AReport.Add(''); + end; for i := 0 to NoToAnalyze - 1 do if (i <> RefCol) then @@ -312,7 +362,6 @@ var AllRefs : boolean; i, j, RowNo, RefColNo, NoToAnalyze : integer; Row, Col, Ncases, Nrows, Ncols, df : integer; - outline : string; ChiSquare, ProbChi : double; yates : boolean; Adjchisqr, Adjprobchi: double; @@ -349,8 +398,7 @@ begin ColNoSelected[i+1] := GetVariableIndex(OS3MainFrm.DataGrid, ColLabels[i]); end; - - // allocate and initialize + // Allocate and initialize SetLength(Freq, NRows+1, NCols+1); SetLength(Prop, NRows+1, NCols+1); SetLength(Expected, NRows, NCols); @@ -361,7 +409,7 @@ begin RowLabels[NRows] := 'Total'; ColLabels[NCols] := 'Total'; - // get cell data + // Get cell data NCases := 0; for i := 1 to NoCases do begin @@ -393,14 +441,15 @@ begin // Then get expected values and cell chi-squares ChiSquare := 0.0; Adjchisqr := 0.0; - yates := YatesChk.Checked and (Nrows = 2) and (Ncols = 2); - if (Nrows > 1) and (Ncols > 1) then + yates := YatesChk.Checked and (NRows = 2) and (NCols = 2); + + if (NRows > 1) and (NCols > 1) then begin - for i := 1 to Nrows do + for i := 1 to NRows do begin - for j := 1 to Ncols do + for j := 1 to NCols do begin - Expected[i-1,j-1] := Freq[Nrows,j-1] * Freq[i-1,Ncols] / Ncases; + 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 @@ -411,22 +460,22 @@ begin ChiSquare := ChiSquare + CellChi[i-1,j-1]; end; end; - df := (Nrows - 1) * (Ncols - 1); + 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 := 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); + AdjProbChi := 1.0 - ChiSquaredProb(AdjChiSqr, df); end; end; - if (Nrows = 1) then // equal probability + if (NRows = 1) then // equal probability begin - for j := 0 to Ncols - 1 do + for j := 0 to NCols - 1 do begin - Expected[0,j] := Ncases / Ncols; + Expected[0,j] := NCases / NCols; if (Expected[0][j] > 0) then CellChi[0,j] := sqr(Freq[0,j] - Expected[0,j]) / Expected[0,j]; ChiSquare := ChiSquare + CellChi[0,j]; @@ -434,7 +483,7 @@ begin df := Ncols - 1; end; - if (Ncols = 1) then // equal probability + if (NCols = 1) then // equal probability begin for i := 0 to Nrows - 1 do begin @@ -448,70 +497,99 @@ begin ProbChi := 1.0 - ChiSquaredProb(ChiSquare, df); // prob. larger chi - //Print results to output form + // Print results to output form lReport := TStringList.Create; try + // Print frequencies tables if requested by user + if ObsChk.Checked or ExpChk.Checked then + begin + FrequenciesPage.TabVisible := true; + + lReport.Add('CHI-SQUARE ANALYSIS RESULTS'); + lReport.Add('No. of Cases: %d', [Ncases]); + + if ObsChk.Checked then + begin + IntArrayPrint(Freq, NRows+1, NCols+1, 'Frequencies', RowLabels, ColLabels, 'OBSERVED FREQUENCIES', lReport); + if ExpChk.Checked then + begin + lReport.Add(DIVIDER_SMALL_AUTO); + lReport.Add(''); + end; + end; + + if ExpChk.Checked then + MatPrint(Expected, Nrows, Ncols, 'EXPECTED FREQUENCIES', RowLabels, ColLabels, NoCases, lReport); + + FFrequenciesReportFrame.DisplayReport(lReport); + lReport.Clear; + end else + FrequenciesPage.TabVisible := false; + + // Print row/col properties + if PropChk.Checked then + begin + RowColPropsPage.TabVisible := true; + + lReport.Add('CHI-SQUARE ANALYSIS RESULTS'); + lReport.Add('No. of Cases: %d', [Ncases]); + + 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, 'ROW PROPORTIONS', RowLabels, ColLabels, NoCases, lReport); + + lReport.Add(DIVIDER_SMALL_AUTO); + lReport.Add(''); + + 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, 'COLUMN PROPORTIONS', RowLabels, ColLabels, NoCases, lReport); + + FRowColPropsReportFrame.DisplayReport(lReport); + lReport.Clear; + end else + RowColPropsPage.TabVisible := false; + + // Print cell chi-sqr values if requested by user + if ChiChk.Checked then + begin + CellChiSqrPage.TabVisible := true; + lReport.Add('CHI-SQUARE ANALYSIS RESULTS'); + lReport.Add('No. of Cases: %d', [Ncases]); + MatPrint(CellChi, Nrows, Ncols, 'CHI-SQUARED VALUE FOR CELLS', RowLabels, ColLabels, NoCases, lReport); + FCellChiSqrReportFrame.DisplayReport(lReport); + lReport.Clear; + end else + CellChiSqrPage.TabVisible := false; + lReport.Add('CHI-SQUARE ANALYSIS RESULTS'); lReport.Add('No. of Cases: %d', [Ncases]); lReport.Add(''); - // print tables requested by use - if ObsChk.Checked then - IntArrayPrint(Freq, Nrows+1, Ncols+1, 'Frequencies', RowLabels, ColLabels, 'OBSERVED FREQUENCIES', lReport); - - if ExpChk.Checked then - begin - outline := 'EXPECTED FREQUENCIES'; - MatPrint(Expected, Nrows, Ncols, outline, RowLabels, ColLabels, NoCases, lReport); - end; - - 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; - - if PropChk.Checked then - begin - outline := 'ROW PROPORTIONS'; - MatPrint(Prop, Nrows+1, Ncols+1, outline, RowLabels, ColLabels, NoCases, lReport); - end; - - 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; - if (PropChk.Checked) then - begin - outline := 'COLUMN PROPORTIONS'; - MatPrint(Prop, Nrows+1, Ncols+1, outline, RowLabels, ColLabels, NoCases, lReport); - end; - - if ChiChk.Checked then - begin - outline := 'CHI-SQUARED VALUE FOR CELLS'; - MatPrint(CellChi, Nrows, Ncols, outline, RowLabels, ColLabels, NoCases, lReport); - end; - lReport.Add(''); lReport.Add( 'Chi-square: %8.3f', [ChiSquare]); lReport.Add( ' with D.F. %8d', [df]); @@ -539,7 +617,6 @@ begin begin phi := sqrt(ChiSquare / Ncases); lReport.Add('phi correlation: %8.4f', [phi]); - lReport.Add(''); pearsonr := 0.0; SumX := 0.0; @@ -558,16 +635,13 @@ begin pearsonr := pearsonr - (SumX * SumY / Ncases); pearsonr := pearsonr / sqrt(VarX * VarY); lReport.Add('Pearson Correlation r: %8.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: %8.3f', [CoefCont]); - lReport.Add(''); if (Nrows < Ncols) then CramerV := sqrt(ChiSquare / (Ncases * ((Nrows-1)))) @@ -577,7 +651,7 @@ begin end; lReport.Add(''); - lReport.Add('============================================================================='); + lReport.Add(DIVIDER_AUTO); lReport.Add(''); // Now do RIDIT analysis @@ -590,7 +664,13 @@ begin for i := 0 to NoToAnalyze - 1 do begin RefColNo := ColNoSelected[i+1] - 2; - Analyze(RefColNo, ColNoSelected, RowLabels,ColLabels, NoToAnalyze, Freq, Prop, Nrows, lReport); + Analyze(RefColNo, RowLabels,ColLabels, NoToAnalyze, Freq, Prop, Nrows, lReport); + if i < NoToAnalyze-1 then + begin + lReport.Add(''); + lReport.Add(DIVIDER_SMALL_AUTO); + lReport.Add(''); + end; end; end else // only one selected reference variable @@ -603,7 +683,7 @@ begin for j := 0 to NoToAnalyze - 1 do if (ColNoSelected[j+1] = RefColNo) then RefColNo := j; - Analyze(RefColNo, ColNoSelected, RowLabels,ColLabels, NoToAnalyze, Freq, Prop, Nrows, lReport); + Analyze(RefColNo, RowLabels,ColLabels, NoToAnalyze, Freq, Prop, Nrows, lReport); end; FReportFrame.DisplayReport(lReport); @@ -627,6 +707,17 @@ var begin inherited; + FrequenciesPage.TabVisible := false; + RowColPropsPage.TabVisible := false; + CellChiSqrPage.TabVisible := false; + + if FFrequenciesReportFrame <> nil then + FFrequenciesReportFrame.Clear; + if FRowColPropsReportFrame <> nil then + FRowColPropsReportframe.Clear; + if FCellChiSqrReportFrame <> nil then + FCellChiSqrReportFrame.Clear; + VarList.Clear; for i := 1 to NoVariables do VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]); @@ -671,7 +762,14 @@ end; procedure TRIDITForm.UpdateBtnStates; begin inherited; - + + if FFrequenciesReportFrame <> nil then + FFrequenciesReportFrame.UpdateBtnStates; + if FRowColPropsReportFrame <> nil then + FRowColPropsReportframe.UpdateBtnStates; + if FCellChiSqrReportFrame <> nil then + FCellChiSqrReportFrame.UpdateBtnStates; + RowIn.Enabled := (VarList.ItemIndex > -1) and (RowEdit.Text = ''); RowOut.Enabled := (RowEdit.Text <> '');