From 02db991125d92562c8bb1fa60b4f7966ffc2fba6 Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Mon, 26 Oct 2020 16:06:42 +0000 Subject: [PATCH] LazStats: Inherit KendallTauUnit from TBasicStatsReportForm. Fix tab order in recently modified forms. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7811 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- applications/lazstats/source/LazStats.lpi | 2 +- .../analysis/nonparametric/kendalltauunit.lfm | 584 ++++----- .../analysis/nonparametric/kendalltauunit.pas | 1093 ++++++++--------- .../analysis/nonparametric/signtestunit.lfm | 18 +- .../analysis/nonparametric/spearmanunit.lfm | 18 +- .../analysis/nonparametric/wilcoxonunit.lfm | 18 +- .../lazstats/source/forms/mainunit.pas | 6 +- 7 files changed, 835 insertions(+), 904 deletions(-) diff --git a/applications/lazstats/source/LazStats.lpi b/applications/lazstats/source/LazStats.lpi index e72d67074..f57439962 100644 --- a/applications/lazstats/source/LazStats.lpi +++ b/applications/lazstats/source/LazStats.lpi @@ -793,7 +793,7 @@ - + diff --git a/applications/lazstats/source/forms/analysis/nonparametric/kendalltauunit.lfm b/applications/lazstats/source/forms/analysis/nonparametric/kendalltauunit.lfm index 628155cf9..7b41be9cc 100644 --- a/applications/lazstats/source/forms/analysis/nonparametric/kendalltauunit.lfm +++ b/applications/lazstats/source/forms/analysis/nonparametric/kendalltauunit.lfm @@ -1,331 +1,277 @@ -object KendallTauFrm: TKendallTauFrm +inherited KendallTauForm: TKendallTauForm Left = 719 - Height = 379 + Height = 361 Top = 350 - Width = 396 + Width = 415 HelpType = htKeyword HelpKeyword = 'html/KendallsTauandPartialTau.htm' - AutoSize = True Caption = 'Kendall Rank Correlation Tau and Partial Tau' - ClientHeight = 379 - ClientWidth = 396 - OnActivate = FormActivate - OnCreate = FormCreate - OnShow = FormShow - Position = poMainFormCenter - LCLVersion = '2.1.0.0' - object Label1: TLabel - AnchorSideLeft.Control = Owner - AnchorSideTop.Control = Owner - Left = 8 - Height = 15 - Top = 8 - Width = 97 - BorderSpacing.Left = 8 - BorderSpacing.Top = 8 - Caption = 'Variables Available' - ParentColor = False - end - object Label2: TLabel - AnchorSideLeft.Control = XEdit - AnchorSideBottom.Control = XEdit - Left = 220 - Height = 15 - Top = 33 - Width = 51 - Anchors = [akLeft, akBottom] - BorderSpacing.Bottom = 2 - Caption = 'X Variable' - ParentColor = False - end - object Label3: TLabel - AnchorSideLeft.Control = YEdit - AnchorSideBottom.Control = YEdit - Left = 220 - Height = 15 - Top = 117 - Width = 51 - Anchors = [akLeft, akBottom] - BorderSpacing.Bottom = 2 - Caption = 'Y Variable' - ParentColor = False - end - object Label4: TLabel - AnchorSideLeft.Control = ZEdit - AnchorSideBottom.Control = ZEdit - Left = 220 - Height = 15 - Top = 201 - Width = 51 - Anchors = [akLeft, akBottom] - BorderSpacing.Bottom = 2 - Caption = 'Z Variable' - ParentColor = False - end - object VarList: TListBox - AnchorSideLeft.Control = Owner - AnchorSideTop.Control = Label1 - AnchorSideTop.Side = asrBottom - AnchorSideRight.Control = XIn - AnchorSideBottom.Control = Bevel1 - Left = 8 - Height = 303 - Top = 25 - Width = 168 - Anchors = [akTop, akLeft, akRight, akBottom] - BorderSpacing.Left = 8 - BorderSpacing.Top = 2 - BorderSpacing.Right = 8 - ItemHeight = 0 - OnSelectionChange = VarListSelectionChange - TabOrder = 0 - end - object XIn: TBitBtn - AnchorSideLeft.Control = Owner - AnchorSideLeft.Side = asrCenter - AnchorSideTop.Control = VarList - Left = 184 - Height = 28 - Top = 25 - Width = 28 - Images = MainDataModule.ImageList - ImageIndex = 1 - OnClick = XInClick - Spacing = 0 - TabOrder = 1 - end - object XOut: TBitBtn - AnchorSideLeft.Control = Owner - AnchorSideLeft.Side = asrCenter - AnchorSideTop.Control = XIn - AnchorSideTop.Side = asrBottom - Left = 184 - Height = 28 - Top = 57 - Width = 28 - BorderSpacing.Top = 4 - Images = MainDataModule.ImageList - ImageIndex = 0 - OnClick = XOutClick - Spacing = 0 - TabOrder = 2 - end - object YIn: TBitBtn - AnchorSideLeft.Control = Owner - AnchorSideLeft.Side = asrCenter - AnchorSideTop.Control = XOut - AnchorSideTop.Side = asrBottom - Left = 184 - Height = 28 - Top = 109 - Width = 28 - BorderSpacing.Top = 24 - Images = MainDataModule.ImageList - ImageIndex = 1 - OnClick = YInClick - Spacing = 0 - TabOrder = 4 - end - object YOut: TBitBtn - AnchorSideLeft.Control = Owner - AnchorSideLeft.Side = asrCenter - AnchorSideTop.Control = YIn - AnchorSideTop.Side = asrBottom - Left = 184 - Height = 28 - Top = 141 - Width = 28 - BorderSpacing.Top = 4 - Images = MainDataModule.ImageList - ImageIndex = 0 - OnClick = YOutClick - Spacing = 0 - TabOrder = 5 - end - object ZIn: TBitBtn - AnchorSideLeft.Control = Owner - AnchorSideLeft.Side = asrCenter - AnchorSideTop.Control = YOut - AnchorSideTop.Side = asrBottom - Left = 184 - Height = 28 - Top = 193 - Width = 28 - BorderSpacing.Top = 24 - Images = MainDataModule.ImageList - ImageIndex = 1 - OnClick = ZInClick - Spacing = 0 - TabOrder = 7 - end - object ZOut: TBitBtn - AnchorSideLeft.Control = Owner - AnchorSideLeft.Side = asrCenter - AnchorSideTop.Control = ZIn - AnchorSideTop.Side = asrBottom - Left = 184 - Height = 28 - Top = 225 - Width = 28 - BorderSpacing.Top = 4 - Images = MainDataModule.ImageList - ImageIndex = 0 - OnClick = ZOutClick - Spacing = 0 - TabOrder = 8 - end - object XEdit: TEdit - AnchorSideLeft.Control = XIn - AnchorSideLeft.Side = asrBottom - AnchorSideRight.Control = Owner - AnchorSideRight.Side = asrBottom - AnchorSideBottom.Control = XOut - AnchorSideBottom.Side = asrBottom - Left = 220 - Height = 23 - Top = 50 - Width = 168 - Anchors = [akLeft, akRight, akBottom] - BorderSpacing.Left = 8 - BorderSpacing.Right = 8 - BorderSpacing.Bottom = 12 - ReadOnly = True - TabOrder = 3 - Text = 'XEdit' - end - object YEdit: TEdit - AnchorSideLeft.Control = YIn - AnchorSideLeft.Side = asrBottom - AnchorSideRight.Control = Owner - AnchorSideRight.Side = asrBottom - AnchorSideBottom.Control = YOut - AnchorSideBottom.Side = asrBottom - Left = 220 - Height = 23 - Top = 134 - Width = 168 - Anchors = [akLeft, akRight, akBottom] - BorderSpacing.Left = 8 - BorderSpacing.Right = 8 - BorderSpacing.Bottom = 12 - ReadOnly = True - TabOrder = 6 - Text = 'Edit1' - end - object ZEdit: TEdit - AnchorSideLeft.Control = ZIn - AnchorSideLeft.Side = asrBottom - AnchorSideRight.Control = Owner - AnchorSideRight.Side = asrBottom - AnchorSideBottom.Control = ZOut - AnchorSideBottom.Side = asrBottom - Left = 220 - Height = 23 - Top = 218 - Width = 168 - Anchors = [akLeft, akRight, akBottom] - BorderSpacing.Left = 8 - BorderSpacing.Right = 8 - BorderSpacing.Bottom = 12 - ReadOnly = True - TabOrder = 9 - Text = 'Edit1' - end - object OptionsGroup: TGroupBox - AnchorSideLeft.Control = XEdit - AnchorSideTop.Control = ZOut - AnchorSideTop.Side = asrBottom - AnchorSideBottom.Control = Bevel1 - Left = 222 - Height = 45 - Top = 277 - Width = 150 - AutoSize = True - BorderSpacing.Left = 2 - BorderSpacing.Top = 24 - BorderSpacing.Bottom = 8 - Caption = 'Options:' - ClientHeight = 25 - ClientWidth = 146 - TabOrder = 10 - object RanksChk: TCheckBox - Left = 12 - Height = 19 + ClientHeight = 361 + ClientWidth = 415 + inherited ParamsPanel: TPanel + Height = 345 + ClientHeight = 345 + inherited CloseBtn: TButton + Top = 320 + TabOrder = 14 + end + inherited ComputeBtn: TButton + Top = 320 + TabOrder = 13 + end + inherited ResetBtn: TButton + Top = 320 + TabOrder = 12 + end + inherited HelpBtn: TButton + Top = 320 + TabOrder = 11 + end + inherited ButtonBevel: TBevel + Top = 304 + end + object Label1: TLabel[5] + AnchorSideLeft.Control = ParamsPanel + AnchorSideTop.Control = ParamsPanel + Left = 0 + Height = 15 Top = 0 - Width = 128 - BorderSpacing.Left = 12 + Width = 97 + Caption = 'Available Variables' + ParentColor = False + end + object Label2: TLabel[6] + AnchorSideLeft.Control = XEdit + AnchorSideBottom.Control = XEdit + Left = 164 + Height = 15 + Top = 21 + Width = 51 + Anchors = [akLeft, akBottom] + BorderSpacing.Bottom = 2 + Caption = 'X Variable' + ParentColor = False + end + object Label3: TLabel[7] + AnchorSideLeft.Control = YEdit + AnchorSideBottom.Control = YEdit + Left = 164 + Height = 15 + Top = 101 + Width = 51 + Anchors = [akLeft, akBottom] + BorderSpacing.Bottom = 2 + Caption = 'Y Variable' + ParentColor = False + end + object Label4: TLabel[8] + AnchorSideLeft.Control = ZEdit + AnchorSideBottom.Control = ZEdit + Left = 164 + Height = 15 + Top = 181 + Width = 51 + Anchors = [akLeft, akBottom] + BorderSpacing.Bottom = 2 + Caption = 'Z Variable' + ParentColor = False + end + object VarList: TListBox[9] + AnchorSideLeft.Control = ParamsPanel + AnchorSideTop.Control = Label1 + AnchorSideTop.Side = asrBottom + AnchorSideRight.Control = XIn + AnchorSideBottom.Control = ButtonBevel + Left = 0 + Height = 287 + Top = 17 + Width = 126 + Anchors = [akTop, akLeft, akRight, akBottom] + BorderSpacing.Top = 2 BorderSpacing.Right = 6 - BorderSpacing.Bottom = 6 - Caption = 'Show Ranked Scores' + ItemHeight = 0 + OnDblClick = VarListDblClick + OnSelectionChange = VarListSelectionChange TabOrder = 0 end + object XIn: TBitBtn[10] + AnchorSideLeft.Control = ParamsPanel + AnchorSideLeft.Side = asrCenter + AnchorSideTop.Control = VarList + Left = 132 + Height = 26 + Top = 17 + Width = 26 + Images = MainDataModule.ImageList + ImageIndex = 1 + OnClick = XInClick + Spacing = 0 + TabOrder = 1 + end + object XOut: TBitBtn[11] + AnchorSideLeft.Control = ParamsPanel + AnchorSideLeft.Side = asrCenter + AnchorSideTop.Control = XIn + AnchorSideTop.Side = asrBottom + Left = 132 + Height = 26 + Top = 47 + Width = 26 + BorderSpacing.Top = 4 + Images = MainDataModule.ImageList + ImageIndex = 0 + OnClick = XOutClick + Spacing = 0 + TabOrder = 2 + end + object YIn: TBitBtn[12] + AnchorSideLeft.Control = ParamsPanel + AnchorSideLeft.Side = asrCenter + AnchorSideTop.Control = XOut + AnchorSideTop.Side = asrBottom + Left = 132 + Height = 26 + Top = 97 + Width = 26 + BorderSpacing.Top = 24 + Images = MainDataModule.ImageList + ImageIndex = 1 + OnClick = YInClick + Spacing = 0 + TabOrder = 4 + end + object YOut: TBitBtn[13] + AnchorSideLeft.Control = ParamsPanel + AnchorSideLeft.Side = asrCenter + AnchorSideTop.Control = YIn + AnchorSideTop.Side = asrBottom + Left = 132 + Height = 26 + Top = 127 + Width = 26 + BorderSpacing.Top = 4 + Images = MainDataModule.ImageList + ImageIndex = 0 + OnClick = YOutClick + Spacing = 0 + TabOrder = 5 + end + object ZIn: TBitBtn[14] + AnchorSideLeft.Control = ParamsPanel + AnchorSideLeft.Side = asrCenter + AnchorSideTop.Control = YOut + AnchorSideTop.Side = asrBottom + Left = 132 + Height = 26 + Top = 177 + Width = 26 + BorderSpacing.Top = 24 + Images = MainDataModule.ImageList + ImageIndex = 1 + OnClick = ZInClick + Spacing = 0 + TabOrder = 7 + end + object ZOut: TBitBtn[15] + AnchorSideLeft.Control = ParamsPanel + AnchorSideLeft.Side = asrCenter + AnchorSideTop.Control = ZIn + AnchorSideTop.Side = asrBottom + Left = 132 + Height = 26 + Top = 207 + Width = 26 + BorderSpacing.Top = 4 + Images = MainDataModule.ImageList + ImageIndex = 0 + OnClick = ZOutClick + Spacing = 0 + TabOrder = 8 + end + object XEdit: TEdit[16] + AnchorSideLeft.Control = XIn + AnchorSideLeft.Side = asrBottom + AnchorSideRight.Control = ParamsPanel + AnchorSideRight.Side = asrBottom + AnchorSideBottom.Control = XOut + AnchorSideBottom.Side = asrBottom + Left = 164 + Height = 23 + Top = 38 + Width = 127 + Anchors = [akLeft, akRight, akBottom] + BorderSpacing.Left = 6 + BorderSpacing.Bottom = 12 + ReadOnly = True + TabOrder = 3 + Text = 'XEdit' + end + object YEdit: TEdit[17] + AnchorSideLeft.Control = YIn + AnchorSideLeft.Side = asrBottom + AnchorSideRight.Control = ParamsPanel + AnchorSideRight.Side = asrBottom + AnchorSideBottom.Control = YOut + AnchorSideBottom.Side = asrBottom + Left = 164 + Height = 23 + Top = 118 + Width = 127 + Anchors = [akLeft, akRight, akBottom] + BorderSpacing.Left = 6 + BorderSpacing.Bottom = 12 + ReadOnly = True + TabOrder = 6 + Text = 'YEdit' + end + object ZEdit: TEdit[18] + AnchorSideLeft.Control = ZIn + AnchorSideLeft.Side = asrBottom + AnchorSideRight.Control = ParamsPanel + AnchorSideRight.Side = asrBottom + AnchorSideBottom.Control = ZOut + AnchorSideBottom.Side = asrBottom + Left = 164 + Height = 23 + Top = 198 + Width = 127 + Anchors = [akLeft, akRight, akBottom] + BorderSpacing.Left = 6 + BorderSpacing.Bottom = 12 + ReadOnly = True + TabOrder = 9 + Text = 'ZEdit' + end + object OptionsGroup: TGroupBox[19] + AnchorSideLeft.Control = ZOut + AnchorSideTop.Control = ZOut + AnchorSideTop.Side = asrBottom + Left = 134 + Height = 45 + Top = 257 + Width = 150 + AutoSize = True + BorderSpacing.Left = 2 + BorderSpacing.Top = 24 + BorderSpacing.Bottom = 8 + Caption = 'Options:' + ClientHeight = 25 + ClientWidth = 146 + TabOrder = 10 + object RanksChk: TCheckBox + Left = 12 + Height = 19 + Top = 0 + Width = 128 + BorderSpacing.Left = 12 + BorderSpacing.Right = 6 + BorderSpacing.Bottom = 6 + Caption = 'Show Ranked Scores' + TabOrder = 0 + end + end end - object ResetBtn: TButton - AnchorSideRight.Control = ComputeBtn - AnchorSideBottom.Control = Owner - AnchorSideBottom.Side = asrBottom - Left = 187 - Height = 25 - Top = 346 - Width = 54 - Anchors = [akRight, akBottom] - AutoSize = True - BorderSpacing.Left = 32 - BorderSpacing.Top = 8 - BorderSpacing.Right = 8 - BorderSpacing.Bottom = 8 - Caption = 'Reset' - OnClick = ResetBtnClick - TabOrder = 11 - end - object ComputeBtn: TButton - AnchorSideRight.Control = CloseBtn - AnchorSideBottom.Control = Owner - AnchorSideBottom.Side = asrBottom - Left = 249 - Height = 25 - Top = 346 - Width = 76 - Anchors = [akRight, akBottom] - AutoSize = True - BorderSpacing.Left = 8 - BorderSpacing.Top = 8 - BorderSpacing.Right = 8 - BorderSpacing.Bottom = 8 - Caption = 'Compute' - OnClick = ComputeBtnClick - TabOrder = 12 - end - object CloseBtn: TButton - AnchorSideRight.Control = Owner - AnchorSideRight.Side = asrBottom - AnchorSideBottom.Control = Owner - AnchorSideBottom.Side = asrBottom - Left = 333 - Height = 25 - Top = 346 - Width = 55 - Anchors = [akRight, akBottom] - AutoSize = True - BorderSpacing.Left = 8 - BorderSpacing.Top = 8 - BorderSpacing.Right = 8 - BorderSpacing.Bottom = 8 - Caption = 'Close' - ModalResult = 11 - TabOrder = 13 - end - object Bevel1: TBevel - AnchorSideLeft.Control = Owner - AnchorSideRight.Control = Owner - AnchorSideRight.Side = asrBottom - AnchorSideBottom.Control = CloseBtn - Left = 0 - Height = 8 - Top = 330 - Width = 396 - Anchors = [akLeft, akRight, akBottom] - BorderSpacing.Top = 2 - Shape = bsBottomLine + inherited ParamsSplitter: TSplitter + Height = 361 end end diff --git a/applications/lazstats/source/forms/analysis/nonparametric/kendalltauunit.pas b/applications/lazstats/source/forms/analysis/nonparametric/kendalltauunit.pas index 750215b37..577a956b6 100644 --- a/applications/lazstats/source/forms/analysis/nonparametric/kendalltauunit.pas +++ b/applications/lazstats/source/forms/analysis/nonparametric/kendalltauunit.pas @@ -7,19 +7,15 @@ unit KendallTauUnit; interface uses - Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, + Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, Buttons, ExtCtrls, - MainUnit, OutputUnit, FunctionsLib, Globals, DataProcs, MatrixLib; + MainUnit, FunctionsLib, Globals, MatrixLib, BasicStatsReportFormUnit; type - { TKendallTauFrm } + { TKendallTauForm } - TKendallTauFrm = class(TForm) - Bevel1: TBevel; - ResetBtn: TButton; - ComputeBtn: TButton; - CloseBtn: TButton; + TKendallTauForm = class(TBasicStatsReportForm) RanksChk: TCheckBox; OptionsGroup: TGroupBox; XEdit: TEdit; @@ -36,12 +32,8 @@ type ZOut: TBitBtn; Label1: TLabel; VarList: TListBox; - procedure ComputeBtnClick(Sender: TObject); - procedure FormActivate(Sender: TObject); - procedure FormCreate(Sender: TObject); - procedure FormShow(Sender: TObject); - procedure ResetBtnClick(Sender: TObject); - procedure VarListSelectionChange(Sender: TObject; User: boolean); + procedure VarListDblClick(Sender: TObject); + procedure VarListSelectionChange(Sender: TObject; {%H-}User: boolean); procedure XInClick(Sender: TObject); procedure XOutClick(Sender: TObject); procedure YInClick(Sender: TObject); @@ -49,573 +41,433 @@ type procedure ZInClick(Sender: TObject); procedure ZOutClick(Sender: TObject); private - { private declarations } - FAutoSized: Boolean; - procedure UpdateBtnStates; + + protected + procedure AdjustConstraints; override; + procedure Compute; override; + procedure UpdateBtnStates; override; + function Validate(out AMsg: String; out AControl: TWinControl): Boolean; override; + public - { public declarations } + procedure Reset; override; end; var - KendallTauFrm: TKendallTauFrm; + KendallTauForm: TKendallTauForm; implementation +{$R *.lfm} + uses - Math; + Math, + GridProcs, MatrixUnit; -{ TKendallTauFrm } +{ TKendallTauForm } -procedure TKendallTauFrm.ResetBtnClick(Sender: TObject); +procedure TKendallTauForm.AdjustConstraints; +begin + inherited; + + ParamsPanel.Constraints.MinWidth := Max( + 4*CloseBtn.Width + 3*CloseBtn.BorderSpacing.Left, + OptionsGroup.Width * 2 - XIn.Width); + ParamsPanel.Constraints.MinHeight := OptionsGroup.Top + OptionsGroup.Height + + ButtonBevel.Height + CloseBtn.BorderSpacing.Top + CloseBtn.Height; +end; + + +procedure TKendallTauForm.Compute; +var + Ranks: DblDyneMat = nil; + X: DblDyneMat = nil; + Index: IntDyneMat = nil; + ColLabels: StrDyneVec = nil; + RowLabels: StrDyneVec = nil; + ColNoSelected: IntdyneVec = nil; + i, j, k, NoTies, NoSelected : integer; + col1, col2, col3, NCases : integer; + Probability, TieSum, Avg, SumT: double; + z, denominator, stddev : double; + TauXY, TauXZ, TauYZ : double; + Tx, Ty, Tz : double; + Term1, Term2 : double; + PartialTau : double; + title : string; + lReport: TStrings; +begin + // Allocate memory + SetLength(index, NoCases, 3); + SetLength(Ranks, NoCases, 3); + SetLength(X, NoCases, 3); + SetLength(ColLabels, 3); + SetLength(RowLabels, NoCases); + SetLength(ColNoSelected, NoVariables); + + Tx := 0.0; + Ty := 0.0; + Tz := 0.0; + + // Get column numbers and labels of variables selected + NoSelected := 0; + ColNoSelected[0] := GetVariableIndex(OS3MainFrm.DataGrid, XEdit.Text); + if ColNoSelected[0] > -1 then inc(NoSelected); + ColNoSelected[1] := GetVariableIndex(OS3MainFrm.DataGrid, YEdit.Text); + if ColNoSelected[1] > -1 then inc(NoSelected); + ColNoSelected[2] := GetVariableIndex(OS3MainFrm.DataGrid, ZEdit.Text); + if ColNoSelected[2] > -1 then inc(NoSelected); + SetLength(ColNoSelected, NoSelected); + + col1 := ColNoSelected[0]; + col2 := ColNoSelected[1]; + if NoSelected = 3 then col3 := ColNoSelected[2] else col3 := -1; + + // Get scores + NCases := 0; + for i := 1 to NoCases do + begin + if not GoodRecord(OS3MainFrm.DataGrid, i, ColNoSelected) then continue; + NCases := NCases + 1; + X[NCases-1, 0] := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[col1, i])); + Ranks[NCases-1, 0] := X[NCases-1, 0]; + X[NCases-1, 1] := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[col2, i])); + Ranks[NCases-1, 1] := X[NCases-1, 1]; + if NoSelected = 3 then + begin + X[NCases-1, 2] := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[col3, i])); + Ranks[NCases-1, 2] := X[NCases-1, 2]; + end; + index[NCases-1, 0] := NCases; + index[NCases-1, 1] := NCases; + if NoSelected = 3 then index[NCases-1, 2] := NCases; + end; + + for i := 0 to NCases - 1 do + RowLabels[i] := IntToStr(i+1); + + // Rank the first variable (X) + for i := 0 to NCases - 2 do + begin + for j := i + 1 to NCases-1 do + begin + if (Ranks[i,0] > Ranks[j, 0]) then // swap + begin + Exchange(Ranks[i, 0], Ranks[j, 0]); + Exchange(Index[i, 0], Index[j, 0]); + end; + end; + end; + + // Assign ranks + for i := 0 to NCases-1 do + Ranks[i,0] := i+1; + + // Check for ties in each + i := 1; + while (i < NCases) do + begin + j := i+1; + TieSum := 0.0; + NoTies := 0; + while (j <= NCases) do + begin + if (X[j-1,0] > X[i-1,0]) then + Break; + if (X[j-1,0] = X[i-1,0]) then + begin + TieSum := TieSum + Ranks[j-1,0]; + NoTies := NoTies + 1; + end; + j := j + 1; + end; + + if (NoTies > 0) then // at least one tie found + begin + TieSum := TieSum + Ranks[i-1,0]; + NoTies := NoTies + 1; + Avg := TieSum / NoTies; + for j := i to i + NoTies - 1 do Ranks[j-1,0] := Avg; + i := i + (NoTies-1); + Tx := Tx + NoTies *(NoTies-1); + end; + i := i + 1; + end; + Tx := Tx / 2.0; + + // Repeat sort for second variable Y + for i := 0 to NCases - 2 do + begin + for j := i + 1 to NCases-1 do + begin + if (Ranks[i,1] > Ranks[j,1]) then // swap + begin + Exchange(Ranks[i, 1], Ranks[j, 1]); + Exchange(index[i, 1], Index[j, 1]); + end; + end; + end; + + // Assign ranks + for i := 0 to NCases-1 do Ranks[i,1] := i+1; + + // Check for ties in each + i := 1; + while (i < NCases) do + begin + j := i+1; + TieSum := 0.0; + NoTies := 0; + while (j <= NoCases) do + begin + if (X[j-1, 1] > X[i-1, 1]) then + Break; + if (X[j-1,1] = X[i-1,1]) then + begin + TieSum := TieSum + Ranks[j-1,1]; + NoTies := NoTies + 1; + end; + j := j + 1; + end; + + if (NoTies > 0) then // at least one tie found + begin + TieSum := TieSum + Ranks[i-1,1]; + NoTies := NoTies + 1; + Avg := TieSum / NoTies; + for j := i to i + NoTies - 1 do Ranks[j-1,1] := Avg; + i := i + (NoTies-1); + Ty := Ty + NoTies * (NoTies - 1); + end; + i := i + 1; + end; + Ty := Ty / 2.0; + + // Repeat for z variable + if NoSelected > 2 then // z was entered + begin + for i := 0 to NCases - 2 do + begin + for j := i + 1 to NCases-1 do + begin + if (Ranks[i,2] > Ranks[j,2]) then // swap + begin + Exchange(Ranks[i, 2], Ranks[j, 2]); + Exchange(Index[i, 2], Index[j, 2]); + end; + end; + end; + + // Assign ranks + for i := 0 to NCases-1 do Ranks[i,2] := i+1; + + // Check for ties in each + i := 1; + while (i < NCases) do + begin + j := i+1; + TieSum := 0.0; + NoTies := 0; + while (j <= NoCases) do + begin + if (X[j-1,2] > X[i-1,2]) then + Break; + if (X[j-1,2] = X[i-1,2]) then + begin + TieSum := TieSum + Ranks[j-1,2]; + NoTies := NoTies + 1; + end; + j := j + 1; + end; + + if (NoTies > 0) then // at least one tie found + begin + TieSum := TieSum + Ranks[i-1,2]; + NoTies := NoTies + 1; + Avg := TieSum / NoTies; + for j := i to i + NoTies - 1 do Ranks[j-1,2] := Avg; + i := i + (NoTies-1); + Tz := Tz + NoTies * (NoTies - 1); + end; + i := i + 1; + end; + Tz := Tz / 2.0; + end; + + // Rearrange ranks into original score order + for k := 1 to 3 do + begin + for i := 1 to NCases - 1 do + begin + for j := i + 1 to NCases do + begin + if (index[i-1,k-1] > index[j-1,k-1]) then // swap + begin + Exchange(Index[i-1, k-1], Index[j-1, k-1]); + Exchange(Ranks[i-1, k-1], Ranks[j-1, k-1]); + end; + end; + end; + end; + + // compute Tau for X and Y + // sort on X and obtain SumT for Y ranks + SumT := 0.0; + for i := 0 to NCases - 2 do + begin + for j := i + 1 to NCases-1 do + begin + if (Ranks[i,0] > Ranks[j,0]) then // swap + begin + Exchange(Ranks[i, 0], Ranks[j, 0]); + Exchange(Ranks[i, 1], Ranks[j, 1]); + if NoSelected = 3 then + Exchange(Ranks[i, 2], Ranks[j, 2]); + Exchange(Index[i, 0], Index[j, 0]); + end; + end; + end; + + for i := 0 to NCases - 2 do + for j := i + 1 to NCases - 1 do + if Ranks[i,1] < Ranks[j,1] then + SumT := SumT + 1.0 + else if Ranks[i,1] > Ranks[j,1] then + SumT := SumT - 1.0; + Term1 := sqrt((NCases * (NCases-1)) / 2.0 - Tx); + Term2 := sqrt((NCases * (Ncases-1)) / 2.0 - Ty); + denominator := Term1 * Term2; + TauXY := SumT / denominator; + + if NoSelected > 2 then // get tau values for partial + begin + // Get TauXZ + SumT := 0.0; + for i := 0 to NCases - 2 do + for j := i + 1 to NCases - 1 do + if Ranks[i,2] < Ranks[j,2] then + SumT := SumT + 1.0 + else if Ranks[i,2] > Ranks[j,2] then + SumT := SumT - 1.0; + Term1 := sqrt((NCases * (NCases-1)) / 2.0 - Tx); + Term2 := sqrt((NCases * (Ncases-1)) / 2.0 - Tz); + denominator := Term1 * Term2; + TauXZ := SumT / denominator; + + // get back to original order then sort on Y + for i := 0 to NCases - 2 do + begin + for j := i + 1 to NCases - 1 do + begin + if index[i,0] > index[j,0] then // swap + begin + Exchange(Ranks[i, 0], Ranks[j, 0]); + Exchange(Ranks[i, 1], Ranks[j, 1]); + Exchange(Ranks[i, 2], Ranks[j, 2]); + Exchange(Index[i, 0], Index[j, 0]); + end; + end; + end; + + // Get TauYZ + for i := 0 to NCases - 2 do // sort on Y variable + begin + for j := i + 1 to NCases-1 do + begin + if (Ranks[i,1] > Ranks[j,1]) then // swap + begin + Exchange(Ranks[i, 1], Ranks[j, 1]); + Exchange(Ranks[i, 2], Ranks[j, 2]); + Exchange(Index[i, 1], Index[j, 1]); + end; + end; + end; + + SumT := 0.0; + for i := 0 to NCases - 2 do + for j := i + 1 to NCases - 1 do + if Ranks[i,2] < Ranks[j,2] then + SumT := SumT + 1.0 + else if Ranks[i,2] > Ranks[j,2] then + SumT := SumT - 1.0; + Term1 := sqrt((NCases * (NCases-1)) / 2.0 - Ty); + Term2 := sqrt((NCases * (Ncases-1)) / 2.0 - Tz); + denominator := Term1 * Term2; + TauYZ := SumT / denominator; + PartialTau := (TauXY - TauXZ * TauYZ) / (sqrt(1.0 - sqr(TauXZ)) * sqrt(1.0 - sqr(TauYZ))); + end; + + lReport := TStringList.Create; + try + lReport.Add('Kendall Tau for File ' + OS3MainFrm.FileNameEdit.Text); + lReport.Add(''); + lReport.Add('Kendall Tau for Variables ' + ColLabels[0] + ' and ' + ColLabels[1]); + + // do significance tests + stddev := sqrt( (2.0 * ( 2.0 * NCases + 5)) / (9.0 * NCases * (NCases - 1.0))); + z := abs(TauXY / stddev); + probability := 1.0 - probz(z); + lReport.Add('Tau = %8.4f z = %8.3f probability > |z| = %4.3f', [TauXY, z, probability]); + if NoSelected > 2 then + begin + lReport.Add(''); + z := abs(TauXZ / stddev); + probability := 1.0 - probz(z); + lReport.Add('Kendall Tau for variables ' + ColLabels[0] + ' and ' + ColLabels[2]); + lReport.Add('Tau = %8.4f z = %8.3f probability > |z| = %4.3f', [TauXZ, z, probability]); + z := abs(TauYZ / stddev); + probability := 1.0 - probz(z); + lReport.Add(''); + lReport.Add('Kendall Tau for variables ' + ColLabels[1] + ' and ' + ColLabels[2]); + lReport.Add('Tau = %8.4f z = %8.3f probability > |z| = %4.3f', [TauYZ, z, probability]); + lReport.Add(''); + lReport.Add('Partial Tau = %8.4f', [PartialTau]); + end; + lReport.Add(''); + lReport.Add('NOTE: Probabilities are for large N (>10)'); + + // print data matrix if option is elected + if RanksChk.Checked then + begin + lReport.Add(''); + lReport.Add('-----------------------------------------------------------------'); + lReport.Add(''); + title := 'Ranks'; + if NoSelected = 2 then + MatPrint(Ranks, NCases, 2, title, RowLabels, ColLabels, NCases, lReport) + else + MatPrint(Ranks, NCases, 3, title, RowLabels, ColLabels, NCases, lReport); + end; + + FReportFrame.DisplayReport(lReport); + finally + lReport.Free; + end; +end; + + +procedure TKendallTauForm.Reset; var i: integer; begin - XEdit.Text := ''; - YEdit.Text := ''; - ZEdit.Text := ''; - RanksChk.Checked := false; + inherited; + XEdit.Clear; + YEdit.Clear; + ZEdit.Clear; VarList.Items.Clear; for i := 1 to NoVariables do VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]); + RanksChk.Checked := false; UpdateBtnStates; end; -procedure TKendallTauFrm.VarListSelectionChange(Sender: TObject; User: boolean); -begin - UpdateBtnStates; -end; -procedure TKendallTauFrm.XInClick(Sender: TObject); -var - index: integer; -begin - index := VarList.ItemIndex; - if (index > -1) and (XEdit.Text = '') then - begin - XEdit.Text := VarList.Items[index]; - VarList.Items.Delete(index); - end; - UpdateBtnStates; -end; - -procedure TKendallTauFrm.XOutClick(Sender: TObject); -begin - if XEdit.Text <> '' then - begin - VarList.Items.Add(XEdit.Text); - XEdit.Text := ''; - end; - UpdateBtnStates; -end; - -procedure TKendallTauFrm.YInClick(Sender: TObject); -var - index: integer; -begin - index := VarList.ItemIndex; - if (index > -1) and (YEdit.Text = '') then - begin - YEdit.Text := VarList.Items[index]; - VarList.Items.Delete(index); - end; - UpdateBtnStates; -end; - -procedure TKendallTauFrm.YOutClick(Sender: TObject); -begin - if YEdit.Text <> '' then - begin - VarList.Items.Add(YEdit.Text); - YEdit.Text := ''; - end; - UpdateBtnStates; -end; - -procedure TKendallTauFrm.ZInClick(Sender: TObject); -var - index: integer; -begin - index := VarList.ItemIndex; - if (index > -1) and (ZEdit.Text = '') then - begin - ZEdit.Text := VarList.Items[index]; - VarList.Items.Delete(index); - end; - UpdateBtnStates; -end; - -procedure TKendallTauFrm.ZOutClick(Sender: TObject); -begin - if ZEdit.Text <> '' then - begin - VarList.Items.Add(YEdit.Text); - ZEdit.Text := ''; - end; - UpdateBtnStates; -end; - -procedure TKendallTauFrm.FormActivate(Sender: TObject); -var - w: Integer; -begin - if FAutoSized then - exit; - - w := MaxValue([ResetBtn.Width, ComputeBtn.Width, CloseBtn.Width]); - ResetBtn.Constraints.MinWidth := w; - ComputeBtn.Constraints.MinWidth := w; - CloseBtn.Constraints.MinWidth := w; - VarList.Constraints.MinHeight := OptionsGroup.Top + OptionsGroup.Height - VarList.Top; - - Constraints.MinWidth := OptionsGroup.Width * 2 + XIn.Width + 4 * VarList.BorderSpacing.Left; - Constraints.MinHeight := Height; - - FAutoSized := True; -end; - -procedure TKendallTauFrm.FormCreate(Sender: TObject); -begin - Assert(OS3MainFrm <> nil); -end; - -procedure TKendallTauFrm.FormShow(Sender: TObject); -begin - ResetBtnClick(self); -end; - -procedure TKendallTauFrm.ComputeBtnClick(Sender: TObject); -var - i, j, k, itemp, NoTies, NoSelected : integer; - col1, col2, col3, NCases : integer; - index : IntDyneMat; - Probability, Temp, TieSum, Avg, SumT: double; - z, denominator, stddev : double; - Ranks, X : DblDyneMat; - cellstring: string; - ColNoSelected : IntdyneVec; - ColLabels : StrDyneVec; - RowLabels : StrDyneVec; - TauXY, TauXZ, TauYZ : double; - Tx, Ty, Tz : double; - Term1, Term2 : double; - PartialTau : double; - title : string; - lReport: TStrings; -begin - if XEdit.Text = '' then - begin - MessageDlg('X variable not selected.', mtError, [mbOK], 0); - exit; - end; - if YEdit.Text = '' then - begin - MessageDlg('Y variable not selected.', mtError, [mbOK], 0); - exit; - end; - - // Allocate memory - SetLength(index,NoCases,3); - SetLength(Ranks,NoCases,3); - SetLength(X,NoCases,3); - SetLength(ColLabels,3); - SetLength(RowLabels,NoCases); - SetLength(ColNoSelected,NoVariables); - Tx := 0.0; - Ty := 0.0; - Tz := 0.0; - - // Get column numbers and labels of variables selected - NoSelected := 0; - for j := 1 to NoVariables do - begin - cellstring := OS3MainFrm.DataGrid.Cells[j,0]; - if cellstring = Xedit.Text then - begin - ColNoSelected[0] := j; - ColLabels[0] := cellstring; - NoSelected := NoSelected + 1; - end; - if cellstring = Yedit.Text then - begin - ColNoSelected[1] := j; - ColLabels[1] := cellstring; - NoSelected := NoSelected + 1; - end; - if cellstring = Zedit.Text then - begin - ColNoSelected[2] := j; - ColLabels[2] := cellstring; - NoSelected := NoSelected + 1; - end; - end; - - // Get scores - NCases := 0; - for i := 1 to NoCases do - begin - if ( not GoodRecord(i,NoSelected,ColNoSelected)) then continue; - NCases := NCases + 1; - col1 := ColNoSelected[0]; - col2 := ColNoSelected[1]; - if NoSelected = 3 then col3 := ColNoSelected[2]; - X[NCases-1,0] := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[col1,i])); - Ranks[NCases-1,0] := X[NCases-1,0]; - X[NCases-1,1] := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[col2,i])); - Ranks[NCases-1,1] := X[NCases-1,1]; - if NoSelected = 3 then - begin - X[NCases-1,2] := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[col3,i])); - Ranks[NCases-1,2] := X[NCases-1,2]; - end; - index[NCases-1,0] := NCases; - index[NCases-1,1] := NCases; - if NoSelected = 3 then index[NCases-1,2] := NCases; - end; - - for i := 0 to NCases - 1 do RowLabels[i] := IntToStr(i+1); - // Rank the first variable (X) - for i := 0 to NCases - 2 do - begin - for j := i + 1 to NCases-1 do - begin - if (Ranks[i,0] > Ranks[j,0]) then // swap - begin - Temp := Ranks[i,0]; - Ranks[i,0] := Ranks[j,0]; - Ranks[j,0] := Temp; - itemp := index[i,0]; - index[i,0] := index[j,0]; - index[j,0] := itemp; - end; - end; - end; - - // Assign ranks - for i := 0 to NCases-1 do Ranks[i,0] := i+1; - - // Check for ties in each - i := 1; - while (i < NCases) do - begin - j := i+1; - TieSum := 0.0; - NoTies := 0; - while (j <= NCases) do - begin - if (X[j-1,0] > X[i-1,0]) then - Break; - if (X[j-1,0] = X[i-1,0]) then - begin - TieSum := TieSum + Ranks[j-1,0]; - NoTies := NoTies + 1; - end; - j := j + 1; - end; - - if (NoTies > 0) then // at least one tie found - begin - TieSum := TieSum + Ranks[i-1,0]; - NoTies := NoTies + 1; - Avg := TieSum / NoTies; - for j := i to i + NoTies - 1 do Ranks[j-1,0] := Avg; - i := i + (NoTies-1); - Tx := Tx + NoTies *(NoTies-1); - end; - i := i + 1; - end; - Tx := Tx / 2.0; - - // Repeat sort for second variable Y - for i := 0 to NCases - 2 do - begin - for j := i + 1 to NCases-1 do - begin - if (Ranks[i,1] > Ranks[j,1]) then // swap - begin - Temp := Ranks[i,1]; - Ranks[i,1] := Ranks[j,1]; - Ranks[j,1] := Temp; - itemp := index[i,1]; - index[i,1] := index[j,1]; - index[j,1] := itemp; - end; - end; - end; - - // Assign ranks - for i := 0 to NCases-1 do Ranks[i,1] := i+1; - - // Check for ties in each - i := 1; - while (i < NCases) do - begin - j := i+1; - TieSum := 0.0; - NoTies := 0; - while (j <= NoCases) do - begin - if (X[j-1,1] > X[i-1,1]) then - Break; - if (X[j-1,1] = X[i-1,1]) then - begin - TieSum := TieSum + Ranks[j-1,1]; - NoTies := NoTies + 1; - end; - j := j + 1; - end; - - if (NoTies > 0) then // at least one tie found - begin - TieSum := TieSum + Ranks[i-1,1]; - NoTies := NoTies + 1; - Avg := TieSum / NoTies; - for j := i to i + NoTies - 1 do Ranks[j-1,1] := Avg; - i := i + (NoTies-1); - Ty := Ty + NoTies * (NoTies - 1); - end; - i := i + 1; - end; - Ty := Ty / 2.0; - - // Repeat for z variable - if NoSelected > 2 then // z was entered - begin - for i := 0 to NCases - 2 do - begin - for j := i + 1 to NCases-1 do - begin - if (Ranks[i,2] > Ranks[j,2]) then // swap - begin - Temp := Ranks[i,2]; - Ranks[i,2] := Ranks[j,2]; - Ranks[j,2] := Temp; - itemp := index[i,2]; - index[i,2] := index[j,2]; - index[j,2] := itemp; - end; - end; - end; - - // Assign ranks - for i := 0 to NCases-1 do Ranks[i,2] := i+1; - - // Check for ties in each - i := 1; - while (i < NCases) do - begin - j := i+1; - TieSum := 0.0; - NoTies := 0; - while (j <= NoCases) do - begin - if (X[j-1,2] > X[i-1,2]) then - Break; - if (X[j-1,2] = X[i-1,2]) then - begin - TieSum := TieSum + Ranks[j-1,2]; - NoTies := NoTies + 1; - end; - j := j + 1; - end; - - if (NoTies > 0) then // at least one tie found - begin - TieSum := TieSum + Ranks[i-1,2]; - NoTies := NoTies + 1; - Avg := TieSum / NoTies; - for j := i to i + NoTies - 1 do Ranks[j-1,2] := Avg; - i := i + (NoTies-1); - Tz := Tz + NoTies * (NoTies - 1); - end; - i := i + 1; - end; - Tz := Tz / 2.0; - end; - - // Rearrange ranks into original score order - for k := 1 to 3 do - begin - for i := 1 to NCases - 1 do - begin - for j := i + 1 to NCases do - begin - if (index[i-1,k-1] > index[j-1,k-1]) then // swap - begin - itemp := index[i-1,k-1]; - index[i-1,k-1] := index[j-1,k-1]; - index[j-1,k-1] := itemp; - Temp := Ranks[i-1,k-1]; - Ranks[i-1,k-1] := Ranks[j-1,k-1]; - Ranks[j-1,k-1] := Temp; - end; - end; - end; - end; - - // compute Tau for X and Y - // sort on X and obtain SumT for Y ranks - SumT := 0.0; - for i := 0 to NCases - 2 do - begin - for j := i + 1 to NCases-1 do - begin - if (Ranks[i,0] > Ranks[j,0]) then // swap - begin - Temp := Ranks[i,0]; - Ranks[i,0] := Ranks[j,0]; - Ranks[j,0] := Temp; - Temp := Ranks[i,1]; - Ranks[i,1] := Ranks[j,1]; - Ranks[j,1] := Temp; - if NoSelected = 3 then - begin - Temp := Ranks[i,2]; - Ranks[i,2] := Ranks[j,2]; - Ranks[j,2] := Temp; - end; - itemp := index[i,0]; - index[i,0] := index[j,0]; - index[j,0] := itemp; - end; - end; - end; - for i := 0 to NCases - 2 do - for j := i + 1 to NCases - 1 do - if Ranks[i,1] < Ranks[j,1] then SumT := SumT + 1.0 - else if Ranks[i,1] > Ranks[j,1] then SumT := SumT - 1.0; - Term1 := sqrt((NCases * (NCases-1)) / 2.0 - Tx); - Term2 := sqrt((NCases * (Ncases-1)) / 2.0 - Ty); - denominator := Term1 * Term2; - TauXY := SumT / denominator; - - if NoSelected > 2 then // get tau values for partial - begin - // Get TauXZ - SumT := 0.0; - for i := 0 to NCases - 2 do - for j := i + 1 to NCases - 1 do - if Ranks[i,2] < Ranks[j,2] then SumT := SumT + 1.0 - else if Ranks[i,2] > Ranks[j,2] then SumT := SumT - 1.0; - Term1 := sqrt((NCases * (NCases-1)) / 2.0 - Tx); - Term2 := sqrt((NCases * (Ncases-1)) / 2.0 - Tz); - denominator := Term1 * Term2; - TauXZ := SumT / denominator; - - // get back to original order then sort on Y - for i := 0 to NCases - 2 do - begin - for j := i + 1 to NCases - 1 do - begin - if index[i,0] > index[j,0] then // swap - begin - Temp := Ranks[i,0]; - Ranks[i,0] := Ranks[j,0]; - Ranks[j,0] := temp; - Temp := Ranks[i,1]; - Ranks[i,1] := Ranks[j,1]; - Ranks[j,1] := Temp; - Temp := Ranks[i,2]; - Ranks[i,2] := Ranks[j,2]; - Ranks[j,2] := Temp; - itemp := index[i,0]; - index[i,0] := index[j,0]; - index[j,0] := itemp; - end; - end; - end; - - // Get TauYZ - for i := 0 to NCases - 2 do // sort on Y variable - begin - for j := i + 1 to NCases-1 do - begin - if (Ranks[i,1] > Ranks[j,1]) then // swap - begin - Temp := Ranks[i,1]; - Ranks[i,1] := Ranks[j,1]; - Ranks[j,1] := Temp; - Temp := Ranks[i,2]; - Ranks[i,2] := Ranks[j,2]; - Ranks[j,2] := Temp; - itemp := index[i,1]; - index[i,1] := index[j,1]; - index[j,1] := itemp; - end; - end; - end; - - SumT := 0.0; - for i := 0 to NCases - 2 do - for j := i + 1 to NCases - 1 do - if Ranks[i,2] < Ranks[j,2] then SumT := SumT + 1.0 - else if Ranks[i,2] > Ranks[j,2] then SumT := SumT - 1.0; - Term1 := sqrt((NCases * (NCases-1)) / 2.0 - Ty); - Term2 := sqrt((NCases * (Ncases-1)) / 2.0 - Tz); - denominator := Term1 * Term2; - TauYZ := SumT / denominator; - PartialTau := (TauXY - TauXZ * TauYZ) / - (sqrt(1.0 - sqr(TauXZ)) * sqrt(1.0 - sqr(TauYZ))); - end; - - lReport := TStringList.Create; - try - lReport.Add('Kendall Tau for File ' + OS3MainFrm.FileNameEdit.Text); - lReport.Add(''); - lReport.Add('Kendall Tau for Variables ' + ColLabels[0] + ' and ' + ColLabels[1]); - - // do significance tests - stddev := sqrt( (2.0 * ( 2.0 * NCases + 5)) / (9.0 * NCases * (NCases - 1.0))); - z := abs(TauXY / stddev); - probability := 1.0 - probz(z); - lReport.Add('Tau = %8.4f z = %8.3f probability > |z| = %4.3f', [TauXY, z, probability]); - if NoSelected > 2 then - begin - lReport.Add(''); - z := abs(TauXZ / stddev); - probability := 1.0 - probz(z); - lReport.Add('Kendall Tau for variables ' + ColLabels[0] + ' and ' + ColLabels[2]); - lReport.Add('Tau = %8.4f z = %8.3f probability > |z| = %4.3f', [TauXZ, z, probability]); - z := abs(TauYZ / stddev); - probability := 1.0 - probz(z); - lReport.Add(''); - lReport.Add('Kendall Tau for variables ' + ColLabels[1] + ' and ' + ColLabels[2]); - lReport.Add('Tau = %8.4f z = %8.3f probability > |z| = %4.3f', [TauYZ, z, probability]); - lReport.Add(''); - lReport.Add('Partial Tau = %8.4f', [PartialTau]); - end; - lReport.Add(''); - lReport.Add('NOTE: Probabilities are for large N (>10)'); - - // print data matrix if option is elected - if RanksChk.Checked then - begin - lReport.Add(''); - lReport.Add('-----------------------------------------------------------------'); - lReport.Add(''); - title := 'Ranks'; - if NoSelected = 2 then - MatPrint(Ranks, NCases, 2, title, RowLabels, ColLabels, NCases, lReport) - else - MatPrint(Ranks, NCases, 3, title, RowLabels, ColLabels, NCases, lReport); - end; - - DisplayReport(lReport); - finally - lReport.Free; - ColNoSelected := nil; - RowLabels := nil; - ColLabels := nil; - X := nil; - Ranks := nil; - index := nil; - end; -end; - -procedure TKendallTauFrm.UpdateBtnStates; +procedure TKendallTauForm.UpdateBtnStates; var i: Integer; lSelected: Boolean; begin + inherited; + lSelected := false; for i:=0 to VarList.Items.Count-1 do if VarList.Selected[i] then @@ -631,8 +483,129 @@ begin ZOut.Enabled := (ZEdit.Text <> ''); end; -initialization - {$I kendalltauunit.lrs} + +function TKendallTauForm.Validate(out AMsg: String; out AControl: TWinControl): Boolean; +begin + Result := false; + + if XEdit.Text = '' then + begin + AMsg := 'X variable not selected.'; + AControl := XEdit; + exit; + end; + + if YEdit.Text = '' then + begin + AMsg := 'Y variable not selected.'; + AControl := YEdit; + exit; + end; + + Result := true; +end; + + +procedure TKendallTauForm.VarListSelectionChange(Sender: TObject; User: boolean); +begin + UpdateBtnStates; +end; + + +procedure TKendallTauForm.VarListDblClick(Sender: TObject); +var + index: Integer; + s: String; +begin + index := VarList.ItemIndex; + if index > -1 then + begin + s := VarList.Items[index]; + if XEdit.Text = '' then + XEdit.Text := s + else + if YEdit.Text = '' then + YEdit.Text := s + else + if ZEdit.Text = '' then + ZEdit.Text := s; + Varlist.Items.Delete(index); + UpdateBtnStates; + end; +end; + +procedure TKendallTauForm.XInClick(Sender: TObject); +var + index: integer; +begin + index := VarList.ItemIndex; + if (index > -1) and (XEdit.Text = '') then + begin + XEdit.Text := VarList.Items[index]; + VarList.Items.Delete(index); + end; + UpdateBtnStates; +end; + + +procedure TKendallTauForm.XOutClick(Sender: TObject); +begin + if XEdit.Text <> '' then + begin + VarList.Items.Add(XEdit.Text); + XEdit.Text := ''; + end; + UpdateBtnStates; +end; + + +procedure TKendallTauForm.YInClick(Sender: TObject); +var + index: integer; +begin + index := VarList.ItemIndex; + if (index > -1) and (YEdit.Text = '') then + begin + YEdit.Text := VarList.Items[index]; + VarList.Items.Delete(index); + end; + UpdateBtnStates; +end; + + +procedure TKendallTauForm.YOutClick(Sender: TObject); +begin + if YEdit.Text <> '' then + begin + VarList.Items.Add(YEdit.Text); + YEdit.Text := ''; + end; + UpdateBtnStates; +end; + + +procedure TKendallTauForm.ZInClick(Sender: TObject); +var + index: integer; +begin + index := VarList.ItemIndex; + if (index > -1) and (ZEdit.Text = '') then + begin + ZEdit.Text := VarList.Items[index]; + VarList.Items.Delete(index); + end; + UpdateBtnStates; +end; + + +procedure TKendallTauForm.ZOutClick(Sender: TObject); +begin + if ZEdit.Text <> '' then + begin + VarList.Items.Add(YEdit.Text); + ZEdit.Text := ''; + end; + UpdateBtnStates; +end; end. - diff --git a/applications/lazstats/source/forms/analysis/nonparametric/signtestunit.lfm b/applications/lazstats/source/forms/analysis/nonparametric/signtestunit.lfm index 04ed87d9d..a2ee18137 100644 --- a/applications/lazstats/source/forms/analysis/nonparametric/signtestunit.lfm +++ b/applications/lazstats/source/forms/analysis/nonparametric/signtestunit.lfm @@ -11,15 +11,19 @@ inherited SignTestFrm: TSignTestFrm ClientHeight = 329 inherited CloseBtn: TButton Top = 304 + TabOrder = 10 end inherited ComputeBtn: TButton Top = 304 + TabOrder = 9 end inherited ResetBtn: TButton Top = 304 + TabOrder = 8 end inherited HelpBtn: TButton Top = 304 + TabOrder = 7 end inherited ButtonBevel: TBevel Top = 288 @@ -74,7 +78,7 @@ inherited SignTestFrm: TSignTestFrm ItemHeight = 0 OnDblClick = VarListDblClick OnSelectionChange = VarListSelectionChange - TabOrder = 4 + TabOrder = 0 end object Var1In: TBitBtn[9] AnchorSideLeft.Control = ParamsPanel @@ -88,7 +92,7 @@ inherited SignTestFrm: TSignTestFrm ImageIndex = 1 OnClick = Var1InClick Spacing = 0 - TabOrder = 5 + TabOrder = 1 end object Var1Out: TBitBtn[10] AnchorSideLeft.Control = ParamsPanel @@ -104,7 +108,7 @@ inherited SignTestFrm: TSignTestFrm ImageIndex = 0 OnClick = Var1OutClick Spacing = 0 - TabOrder = 6 + TabOrder = 2 end object Var2In: TBitBtn[11] AnchorSideLeft.Control = ParamsPanel @@ -120,7 +124,7 @@ inherited SignTestFrm: TSignTestFrm ImageIndex = 1 OnClick = Var2InClick Spacing = 0 - TabOrder = 7 + TabOrder = 4 end object Var2Out: TBitBtn[12] AnchorSideLeft.Control = ParamsPanel @@ -136,7 +140,7 @@ inherited SignTestFrm: TSignTestFrm ImageIndex = 0 OnClick = Var2OutClick Spacing = 0 - TabOrder = 8 + TabOrder = 5 end object Var1Edit: TEdit[13] AnchorSideLeft.Control = Var1In @@ -153,7 +157,7 @@ inherited SignTestFrm: TSignTestFrm BorderSpacing.Left = 8 BorderSpacing.Bottom = 12 ReadOnly = True - TabOrder = 9 + TabOrder = 3 Text = 'Var1Edit' end object Var2Edit: TEdit[14] @@ -171,7 +175,7 @@ inherited SignTestFrm: TSignTestFrm BorderSpacing.Left = 8 BorderSpacing.Bottom = 12 ReadOnly = True - TabOrder = 10 + TabOrder = 6 Text = 'Var2Edit' end end diff --git a/applications/lazstats/source/forms/analysis/nonparametric/spearmanunit.lfm b/applications/lazstats/source/forms/analysis/nonparametric/spearmanunit.lfm index 00d373ef5..bcfee2a0c 100644 --- a/applications/lazstats/source/forms/analysis/nonparametric/spearmanunit.lfm +++ b/applications/lazstats/source/forms/analysis/nonparametric/spearmanunit.lfm @@ -13,15 +13,19 @@ inherited SpearmanForm: TSpearmanForm ClientHeight = 331 inherited CloseBtn: TButton Top = 306 + TabOrder = 10 end inherited ComputeBtn: TButton Top = 306 + TabOrder = 9 end inherited ResetBtn: TButton Top = 306 + TabOrder = 8 end inherited HelpBtn: TButton Top = 306 + TabOrder = 7 end inherited ButtonBevel: TBevel Top = 290 @@ -78,7 +82,7 @@ inherited SpearmanForm: TSpearmanForm ItemHeight = 0 OnDblClick = VarListDblClick OnSelectionChange = VarListSelectionChange - TabOrder = 4 + TabOrder = 0 end object XIn: TBitBtn[9] AnchorSideLeft.Control = ParamsPanel @@ -92,7 +96,7 @@ inherited SpearmanForm: TSpearmanForm ImageIndex = 1 OnClick = XInClick Spacing = 0 - TabOrder = 5 + TabOrder = 1 end object XOut: TBitBtn[10] AnchorSideLeft.Control = ParamsPanel @@ -108,7 +112,7 @@ inherited SpearmanForm: TSpearmanForm ImageIndex = 0 OnClick = XOutClick Spacing = 0 - TabOrder = 6 + TabOrder = 2 end object YIn: TBitBtn[11] AnchorSideLeft.Control = ParamsPanel @@ -124,7 +128,7 @@ inherited SpearmanForm: TSpearmanForm ImageIndex = 1 OnClick = YInClick Spacing = 0 - TabOrder = 7 + TabOrder = 4 end object YOut: TBitBtn[12] AnchorSideLeft.Control = ParamsPanel @@ -140,7 +144,7 @@ inherited SpearmanForm: TSpearmanForm ImageIndex = 0 OnClick = YOutClick Spacing = 0 - TabOrder = 8 + TabOrder = 5 end object XEdit: TEdit[13] AnchorSideLeft.Control = XIn @@ -157,7 +161,7 @@ inherited SpearmanForm: TSpearmanForm BorderSpacing.Left = 8 BorderSpacing.Bottom = 12 ReadOnly = True - TabOrder = 9 + TabOrder = 3 Text = 'XEdit' end object YEdit: TEdit[14] @@ -175,7 +179,7 @@ inherited SpearmanForm: TSpearmanForm BorderSpacing.Left = 8 BorderSpacing.Bottom = 12 ReadOnly = True - TabOrder = 10 + TabOrder = 6 Text = 'YEdit' end end diff --git a/applications/lazstats/source/forms/analysis/nonparametric/wilcoxonunit.lfm b/applications/lazstats/source/forms/analysis/nonparametric/wilcoxonunit.lfm index 79ce5ad4b..d2977e47b 100644 --- a/applications/lazstats/source/forms/analysis/nonparametric/wilcoxonunit.lfm +++ b/applications/lazstats/source/forms/analysis/nonparametric/wilcoxonunit.lfm @@ -13,15 +13,19 @@ inherited WilcoxonForm: TWilcoxonForm ClientHeight = 278 inherited CloseBtn: TButton Top = 253 + TabOrder = 10 end inherited ComputeBtn: TButton Top = 253 + TabOrder = 9 end inherited ResetBtn: TButton Top = 253 + TabOrder = 8 end inherited HelpBtn: TButton Top = 253 + TabOrder = 7 end inherited ButtonBevel: TBevel Top = 237 @@ -76,7 +80,7 @@ inherited WilcoxonForm: TWilcoxonForm ItemHeight = 0 OnDblClick = VarListDblClick OnSelectionChange = VarListSelectionChange - TabOrder = 4 + TabOrder = 0 end object Var1In: TBitBtn[9] AnchorSideLeft.Control = ParamsPanel @@ -90,7 +94,7 @@ inherited WilcoxonForm: TWilcoxonForm ImageIndex = 1 OnClick = Var1InClick Spacing = 0 - TabOrder = 5 + TabOrder = 1 end object Var1Out: TBitBtn[10] AnchorSideLeft.Control = ParamsPanel @@ -106,7 +110,7 @@ inherited WilcoxonForm: TWilcoxonForm ImageIndex = 0 OnClick = Var1OutClick Spacing = 0 - TabOrder = 6 + TabOrder = 2 end object Var2In: TBitBtn[11] AnchorSideLeft.Control = ParamsPanel @@ -122,7 +126,7 @@ inherited WilcoxonForm: TWilcoxonForm ImageIndex = 1 OnClick = Var2InClick Spacing = 0 - TabOrder = 7 + TabOrder = 4 end object Var2Out: TBitBtn[12] AnchorSideLeft.Control = ParamsPanel @@ -138,7 +142,7 @@ inherited WilcoxonForm: TWilcoxonForm ImageIndex = 0 OnClick = Var2OutClick Spacing = 0 - TabOrder = 8 + TabOrder = 5 end object Var1Edit: TEdit[13] AnchorSideLeft.Control = Var1In @@ -156,7 +160,7 @@ inherited WilcoxonForm: TWilcoxonForm BorderSpacing.Left = 8 BorderSpacing.Bottom = 12 ReadOnly = True - TabOrder = 9 + TabOrder = 3 Text = 'Var1Edit' end object Var2Edit: TEdit[14] @@ -174,7 +178,7 @@ inherited WilcoxonForm: TWilcoxonForm BorderSpacing.Left = 8 BorderSpacing.Bottom = 12 ReadOnly = True - TabOrder = 10 + TabOrder = 6 Text = 'Var2Edit' end end diff --git a/applications/lazstats/source/forms/mainunit.pas b/applications/lazstats/source/forms/mainunit.pas index 2c2148515..d696550d5 100644 --- a/applications/lazstats/source/forms/mainunit.pas +++ b/applications/lazstats/source/forms/mainunit.pas @@ -1904,9 +1904,9 @@ end; // Menu "Analysis" > "Nonparametric" > Kendall's Tau and Partial Tau" procedure TOS3MainFrm.mnuAnalysisNonPar_TauClick(Sender: TObject); begin - if KendallTauFrm = nil then - Application.CreateForm(TKendallTauFrm, KendallTauFrm); - KendallTauFrm.ShowModal; + if KendallTauForm = nil then + Application.CreateForm(TKendallTauForm, KendallTauForm); + KendallTauForm.Show; end; // Menu "Analysis" > "Nonparametric" > "Kaplan-Meier Survival Analysis"