diff --git a/applications/lazstats/source/forms/analysis/nonparametric/riditunit.lfm b/applications/lazstats/source/forms/analysis/nonparametric/riditunit.lfm index 5f0ff2eba..a2bb982d2 100644 --- a/applications/lazstats/source/forms/analysis/nonparametric/riditunit.lfm +++ b/applications/lazstats/source/forms/analysis/nonparametric/riditunit.lfm @@ -16,19 +16,23 @@ inherited RIDITForm: TRIDITForm inherited CloseBtn: TButton Left = 361 Top = 436 + TabOrder = 7 end inherited ComputeBtn: TButton Left = 277 Top = 436 + TabOrder = 6 end inherited ResetBtn: TButton Left = 215 Top = 436 + TabOrder = 5 end inherited HelpBtn: TButton Tag = 143 Left = 156 Top = 436 + TabOrder = 4 end inherited ButtonBevel: TBevel Top = 420 @@ -44,7 +48,7 @@ inherited RIDITForm: TRIDITForm AnchorSideBottom.Side = asrBottom Left = 265 Height = 71 - Top = 349 + Top = 227 Width = 88 Alignment = taRightJustify Anchors = [akTop, akLeft, akBottom] @@ -56,13 +60,13 @@ inherited RIDITForm: TRIDITForm ParentColor = False WordWrap = True end - object GroupBox1: TGroupBox[6] + object OptionsGroup: TGroupBox[6] AnchorSideLeft.Control = RefGrp AnchorSideRight.Side = asrBottom - AnchorSideBottom.Control = RefGrp + AnchorSideBottom.Control = ButtonBevel Left = 0 Height = 114 - Top = 222 + Top = 306 Width = 422 Anchors = [akLeft, akBottom] AutoSize = True @@ -77,7 +81,7 @@ inherited RIDITForm: TRIDITForm ChildSizing.ControlsPerLine = 2 ClientHeight = 94 ClientWidth = 418 - TabOrder = 4 + TabOrder = 3 object ObsChk: TCheckBox Left = 12 Height = 19 @@ -144,10 +148,10 @@ inherited RIDITForm: TRIDITForm AnchorSideTop.Side = asrBottom AnchorSideRight.Control = Owner AnchorSideRight.Side = asrBottom - AnchorSideBottom.Control = ButtonBevel + AnchorSideBottom.Control = OptionsGroup Left = 0 Height = 72 - Top = 348 + Top = 226 Width = 257 Anchors = [akLeft, akBottom] AutoFill = True @@ -171,7 +175,7 @@ inherited RIDITForm: TRIDITForm 'Use only the reference variable selected' ) OnClick = RefGrpClick - TabOrder = 5 + TabOrder = 1 end object AlphaEdit: TEdit[8] AnchorSideLeft.Control = AlphaLabel @@ -181,14 +185,13 @@ inherited RIDITForm: TRIDITForm AnchorSideRight.Side = asrBottom Left = 361 Height = 23 - Top = 373 + Top = 251 Width = 50 Alignment = taRightJustify BorderSpacing.Left = 8 BorderSpacing.Top = 8 - BorderSpacing.Right = 8 BorderSpacing.Bottom = 8 - TabOrder = 6 + TabOrder = 2 Text = 'AlphaEdit' end object Panel1: TPanel[9] @@ -196,7 +199,7 @@ inherited RIDITForm: TRIDITForm AnchorSideTop.Control = ParamsPanel AnchorSideRight.Control = ParamsPanel AnchorSideRight.Side = asrBottom - AnchorSideBottom.Control = GroupBox1 + AnchorSideBottom.Control = RefGrp Left = 0 Height = 214 Top = 0 @@ -206,7 +209,7 @@ inherited RIDITForm: TRIDITForm BevelOuter = bvNone ClientHeight = 214 ClientWidth = 416 - TabOrder = 7 + TabOrder = 0 object Label1: TLabel AnchorSideLeft.Control = Panel1 AnchorSideTop.Control = Panel1 @@ -366,11 +369,10 @@ inherited RIDITForm: TRIDITForm Left = 230 Height = 40 Top = 118 - Width = 178 + Width = 186 Anchors = [akTop, akLeft, akRight, akBottom] BorderSpacing.Left = 8 BorderSpacing.Top = 2 - BorderSpacing.Right = 8 ItemHeight = 0 OnClick = ColListClick OnDblClick = ColListDblClick @@ -387,10 +389,9 @@ inherited RIDITForm: TRIDITForm Left = 230 Height = 23 Top = 191 - Width = 178 + Width = 186 Anchors = [akLeft, akRight, akBottom] BorderSpacing.Left = 8 - BorderSpacing.Right = 8 ReadOnly = True TabOrder = 7 Text = 'RefEdit' diff --git a/applications/lazstats/source/forms/analysis/nonparametric/riditunit.pas b/applications/lazstats/source/forms/analysis/nonparametric/riditunit.pas index b8b344b4f..999addea6 100644 --- a/applications/lazstats/source/forms/analysis/nonparametric/riditunit.pas +++ b/applications/lazstats/source/forms/analysis/nonparametric/riditunit.pas @@ -32,7 +32,7 @@ type YatesChk: TCheckBox; DetailsChk: TCheckBox; ColList: TListBox; - GroupBox1: TGroupBox; + OptionsGroup: TGroupBox; RefEdit: TEdit; Label4: TLabel; RowEdit: TEdit; @@ -145,12 +145,12 @@ begin ParamsPanel.Constraints.MinWidth := MaxValue([ CloseBtn.Width * 4 + CloseBtn.BorderSpacing.Left * 3, - GroupBox1.Width, + OptionsGroup.Width, AlphaEdit.Left + AlphaEdit.Width ]); ParamsPanel.Constraints.MinHeight := ColOut.Top + ColOut.Height + Label4.BorderSpacing.Top + Label4.Height + Label4.BorderSpacing.Bottom + RefEdit.Height + - Panel1.BorderSpacing.Bottom + GroupBox1.Height + RefGrp.Height + + Panel1.BorderSpacing.Bottom + OptionsGroup.Height + RefGrp.Height + ButtonBevel.Height + CloseBtn.BorderSpacing.Top + CloseBtn.Height; end; @@ -164,7 +164,7 @@ var sizes : DblDyneVec = nil; meanridits : DblDyneVec = nil; StdErr : DblDyneVec = nil; - Cratios : DblDyneVec = nil; + CRatios : DblDyneVec = nil; OverMeanRidit : double; chisquare : double; probchi : double; @@ -180,7 +180,7 @@ begin SetLength(refprob,NoRows,4); SetLength(sizes,NoToAnalyze); SetLength(meanridits,NoToAnalyze); - SetLength(Cratios,NoToAnalyze); + SetLength(CRatios,NoToAnalyze); SetLength(StdErr,NoToAnalyze); alpha := StrToFloat(AlphaEdit.Text); @@ -189,7 +189,8 @@ begin AReport.Add('ANALYSIS FOR STANDARD %s', [ColLabels[RefCol]]); AReport.Add(''); -{ +{ --- wp: these data are displayed in separate tabs, no need to repeat them. + // print frequencies outline := 'Frequencies Observed'; IntArrayPrint(Freq, NoRows, NoToAnalyze, 'Frequencies', RowLabels, ColLabels, outline, AReport); @@ -275,16 +276,16 @@ begin AReport.Add(' with probability < %8.4f', [probchi]); // do pairwise comparisons - Cratios[RefCol] := 0.0; + CRatios[RefCol] := 0.0; for i := 0 to NoToAnalyze - 1 do if (i <> RefCol) then begin StdErr[i] := sqrt(sizes[RefCol] + sizes[i]) / (2.0 * sqrt(3.0 * sizes[RefCol] * sizes[i])); - Cratios[i] := (meanridits[i] - 0.5) / StdErr[i]; + CRatios[i] := (meanridits[i] - 0.5) / StdErr[i]; end; outline := 'z critical ratios'; - DynVectorPrint(Cratios, NoToAnalyze, outline, ColLabels, NoCases, AReport); + DynVectorPrint(CRatios, NoToAnalyze, outline, ColLabels, NoCases, AReport); alpha := alpha / 2.0; if BonChk.Checked then @@ -298,19 +299,11 @@ begin for i := 0 to NoToAnalyze - 1 do if (i <> RefCol) then begin - if (abs(Cratios[i]) > Bonferroni) then + if (abs(CRatios[i]) > Bonferroni) then AReport.Add('%s vs %s: significant', [ColLabels[i], ColLabels[RefCol]]) else AReport.Add('%s vs %s: not significant', [ColLabels[i], ColLabels[RefCol]]); end; - - // cleanup - StdErr := nil; - Cratios := nil; - meanridits := nil; - sizes := nil; - refprob := nil; - probdists := nil; end; @@ -549,32 +542,32 @@ begin lReport.Add(''); lReport.Add(''); - lReport.Add( 'Chi-square: %8.3f', [ChiSquare]); - lReport.Add( ' with D.F. %8d', [df]); - lReport.Add( ' and probability > value: %8.3f', [ProbChi]); + lReport.Add( 'Chi-square: %8.3f', [ChiSquare]); + lReport.Add( ' with D.F. %8d', [df]); + lReport.Add( ' and probability > value: %8.3f', [ProbChi]); lReport.Add(''); if yates then begin - lReport.Add('Chi-square using Yates correction: %8.3f', [AdjChiSqr]); - lReport.Add(' and probability > value: %8.3f', [Adjprobchi]); + lReport.Add('Chi-square using Yates correction: %8.3f', [AdjChiSqr]); + lReport.Add(' and probability > value: %8.3f', [AdjProbChi]); end; 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])); + 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: %8.3f', [likelihood]); - lReport.Add( ' with probability > value: %8.4f', [problikelihood]); + lReport.Add( 'Likelihood Ratio: %8.3f', [likelihood]); + lReport.Add( ' with probability > value: %8.3f', [probLikelihood]); lReport.Add(''); if ((Nrows > 1) and (Ncols > 1)) then begin phi := sqrt(ChiSquare / Ncases); - lReport.Add('phi Correlation: %8.4f', [phi]); + lReport.Add('phi Correlation: %8.3f', [phi]); pearsonr := 0.0; SumX := 0.0; @@ -592,20 +585,21 @@ begin pearsonr := pearsonr + ((i+1)*(j+1) * Freq[i,j]); pearsonr := pearsonr - (SumX * SumY / Ncases); pearsonr := pearsonr / sqrt(VarX * VarY); - lReport.Add('Pearson Correlation r: %8.4f', [pearsonr]); + lReport.Add('Pearson Correlation r: %8.3f', [pearsonr]); 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('Mantel-Haenszel Test of Linear Association: %8.3f', [MantelHaenszel]); + lReport.Add(' with probability > value %8.3f', [MHprob]); CoefCont := sqrt(ChiSquare / (ChiSquare + Ncases)); - lReport.Add('The coefficient of contingency: %8.3f', [CoefCont]); + lReport.Add('The coefficient of contingency: %8.3f', [CoefCont]); if (Nrows < Ncols) then CramerV := sqrt(ChiSquare / (Ncases * ((Nrows-1)))) else CramerV := sqrt(ChiSquare / (Ncases * ((Ncols-1)))); - lReport.Add('Cramers V: %8.3f', [CramerV]); + lReport.Add('Cramers V: %8.3f', [CramerV]); end; lReport.Add(''); @@ -626,7 +620,6 @@ begin if i < NoToAnalyze-1 then begin lReport.Add(''); -// lReport.Add(DIVIDER_SMALL_AUTO); lReport.Add(DIVIDER_AUTO); lReport.Add(''); end; @@ -701,35 +694,6 @@ begin end; end; - (* - 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; - end; - *) - - // Equal probability if (numRows = 1) then begin @@ -823,12 +787,12 @@ begin VarList.Clear; for i := 1 to NoVariables do - VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]); + VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i, 0]); ColList.Clear; RowEdit.Clear; RefEdit.Clear; AlphaEdit.Text := FormatFloat('0.00', DEFAULT_ALPHA_LEVEL); - BonChk.Checked := true; + BonChk.Checked := false; Label4.Visible := false; RefEdit.Visible := false; RefGrp.ItemIndex := 0; @@ -887,6 +851,13 @@ var begin Result := false; + if ColList.Count = 0 then + begin + AControl := ColList; + AMsg := 'No column variable(s) selected.'; + exit; + end; + if AlphaEdit.Text = '' then begin AControl := AlphaEdit; diff --git a/applications/lazstats/source/units/functionslib.pas b/applications/lazstats/source/units/functionslib.pas index bcc611b37..7268565c9 100644 --- a/applications/lazstats/source/units/functionslib.pas +++ b/applications/lazstats/source/units/functionslib.pas @@ -6,14 +6,15 @@ interface uses Forms, Controls, LResources, ExtCtrls, Classes, SysUtils, Globals, - Graphics, Dialogs, Math, + //Graphics, + Dialogs, Math, MainUnit, dataprocs; function chisquaredprob(X : double; k : integer) : double; procedure matinv(VAR a, vtimesw, v, w: DblDyneMat; n: integer); function sign(a,b: double): double; function isign(a,b : integer): integer; -function inversez(prob : double) : double; +function InverseZ(Prob: double): double; function zprob(p : double; VAR errorstate : boolean) : double; function probz(z : double) : double; function simpsonintegral(a,b : real) : real; @@ -402,20 +403,21 @@ BEGIN END; //------------------------------------------------------------------- -function inversez(prob : double) : double; +{ Obtains the inverse of z, that is, the z for a probability associated + with a normally distributed z score. } +function InverseZ(prob: double): double; var - z, p : double; - flag : boolean = false; + z, p: double; + err: boolean = false; begin - // obtains the inverse of z, that is, the z for a probability associated - // with a normally distributed z score. - p := prob; - if (prob > 0.5) then p := 1.0 - prob; - z := zprob(p,flag); - if (prob > 0.5) then z := abs(z); - inversez := z; + if (prob > 0.5) then + p := 1.0 - prob + else + p := prob; + z := zprob(p, err); + if (prob > 0.5) then z := abs(z); + Result := z; end; //End of inversez Function -//------------------------------------------------------------------- function zprob(p : double; VAR errorstate : boolean) : double; VAR