From d58dee4816d9659a79120e3c0e7e410889fd7b57 Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Mon, 6 Apr 2020 10:38:45 +0000 Subject: [PATCH] LazStats: Refactor GLMUnit. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7360 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- .../lazstats/docs/HelpNDoc/LazStats.hnd | Bin 5459968 -> 5537792 bytes .../forms/analysis/comparisons/glmunit.lfm | 107 +- .../forms/analysis/comparisons/glmunit.pas | 3125 +++++++++-------- 3 files changed, 1661 insertions(+), 1571 deletions(-) diff --git a/applications/lazstats/docs/HelpNDoc/LazStats.hnd b/applications/lazstats/docs/HelpNDoc/LazStats.hnd index 3f8658a1757f0ff7cc4c0a5a381749bb3c2cfb56..c746946d3cb71d3fb7a08366820d98609a8afc0a 100644 GIT binary patch delta 44657 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 diff --git a/applications/lazstats/source/forms/analysis/comparisons/glmunit.lfm b/applications/lazstats/source/forms/analysis/comparisons/glmunit.lfm index dd6a980cf..47ace1f79 100644 --- a/applications/lazstats/source/forms/analysis/comparisons/glmunit.lfm +++ b/applications/lazstats/source/forms/analysis/comparisons/glmunit.lfm @@ -11,92 +11,74 @@ object GLMFrm: TGLMFrm OnShow = FormShow LCLVersion = '2.1.0.0' object ResetBtn: TButton - AnchorSideRight.Control = CancelBtn + AnchorSideRight.Control = ComputeBtn AnchorSideBottom.Control = Owner AnchorSideBottom.Side = asrBottom - Left = 561 + Left = 653 Height = 25 Top = 533 Width = 54 Anchors = [akRight, akBottom] AutoSize = True - BorderSpacing.Left = 12 + BorderSpacing.Left = 8 BorderSpacing.Top = 8 - BorderSpacing.Right = 12 + BorderSpacing.Right = 8 BorderSpacing.Bottom = 8 Caption = 'Reset' OnClick = ResetBtnClick TabOrder = 3 end - object CancelBtn: TButton - AnchorSideRight.Control = ComputeBtn - AnchorSideBottom.Control = Owner - AnchorSideBottom.Side = asrBottom - Left = 627 - Height = 25 - Top = 533 - Width = 62 - Anchors = [akRight, akBottom] - AutoSize = True - BorderSpacing.Left = 12 - BorderSpacing.Top = 8 - BorderSpacing.Right = 12 - BorderSpacing.Bottom = 8 - Caption = 'Cancel' - ModalResult = 2 - TabOrder = 4 - end object ComputeBtn: TButton - AnchorSideRight.Control = ReturnBtn + AnchorSideRight.Control = CloseBtn AnchorSideBottom.Control = Owner AnchorSideBottom.Side = asrBottom - Left = 701 + Left = 715 Height = 25 Top = 533 Width = 76 Anchors = [akRight, akBottom] AutoSize = True - BorderSpacing.Left = 12 + BorderSpacing.Left = 8 BorderSpacing.Top = 8 - BorderSpacing.Right = 12 + BorderSpacing.Right = 8 BorderSpacing.Bottom = 8 Caption = 'Compute' OnClick = ComputeBtnClick - TabOrder = 5 + TabOrder = 4 end - object ReturnBtn: TButton + object CloseBtn: TButton AnchorSideRight.Control = Owner AnchorSideRight.Side = asrBottom AnchorSideBottom.Control = Owner AnchorSideBottom.Side = asrBottom - Left = 789 + Left = 799 Height = 25 Top = 533 - Width = 61 + Width = 55 Anchors = [akRight, akBottom] AutoSize = True - BorderSpacing.Left = 12 + BorderSpacing.Left = 8 BorderSpacing.Top = 8 - BorderSpacing.Right = 12 + BorderSpacing.Right = 8 BorderSpacing.Bottom = 8 - Caption = 'Return' - ModalResult = 1 - TabOrder = 6 + Caption = 'Close' + ModalResult = 11 + TabOrder = 5 end object HelpBtn: TButton Tag = 126 AnchorSideRight.Control = ResetBtn AnchorSideBottom.Control = Owner AnchorSideBottom.Side = asrBottom - Left = 498 + Left = 594 Height = 25 Top = 533 Width = 51 Anchors = [akRight, akBottom] AutoSize = True - BorderSpacing.Left = 12 + BorderSpacing.Left = 8 BorderSpacing.Top = 8 - BorderSpacing.Right = 12 + BorderSpacing.Right = 8 BorderSpacing.Bottom = 8 Caption = 'Help' OnClick = HelpBtnClick @@ -106,7 +88,7 @@ object GLMFrm: TGLMFrm AnchorSideLeft.Control = Owner AnchorSideRight.Control = Owner AnchorSideRight.Side = asrBottom - AnchorSideBottom.Control = ReturnBtn + AnchorSideBottom.Control = CloseBtn Left = 0 Height = 8 Top = 517 @@ -221,6 +203,7 @@ object GLMFrm: TGLMFrm BorderSpacing.Top = 2 BorderSpacing.Right = 8 ItemHeight = 0 + OnSelectionChange = ContDepCodeSelectionChange TabOrder = 1 end object ContDepCode: TListBox @@ -237,6 +220,7 @@ object GLMFrm: TGLMFrm BorderSpacing.Left = 8 BorderSpacing.Top = 2 ItemHeight = 0 + OnSelectionChange = ContDepCodeSelectionChange TabOrder = 0 end object ContDepInBtn: TBitBtn @@ -250,7 +234,7 @@ object GLMFrm: TGLMFrm Anchors = [akTop, akRight] BorderSpacing.Right = 8 Images = MainDataModule.ImageList - ImageIndex = 1 + ImageIndex = 0 OnClick = ContDepInBtnClick Spacing = 0 TabOrder = 2 @@ -268,7 +252,7 @@ object GLMFrm: TGLMFrm BorderSpacing.Top = 4 BorderSpacing.Right = 8 Images = MainDataModule.ImageList - ImageIndex = 0 + ImageIndex = 1 OnClick = ContDepOutBtnClick Spacing = 0 TabOrder = 3 @@ -345,6 +329,7 @@ object GLMFrm: TGLMFrm BorderSpacing.Top = 2 BorderSpacing.Right = 8 ItemHeight = 0 + OnSelectionChange = ContDepCodeSelectionChange TabOrder = 1 end object CatDepCode: TListBox @@ -359,6 +344,7 @@ object GLMFrm: TGLMFrm Anchors = [akTop, akLeft, akBottom] BorderSpacing.Left = 8 ItemHeight = 0 + OnSelectionChange = ContDepCodeSelectionChange TabOrder = 0 end end @@ -382,7 +368,7 @@ object GLMFrm: TGLMFrm Caption = 'Repeated Meas. Dep. Vars.' ParentColor = False end - object RepDepInBtn: TBitBtn + object ReptDepInBtn: TBitBtn AnchorSideTop.Control = RepeatList AnchorSideRight.Control = Panel8 AnchorSideRight.Side = asrBottom @@ -394,12 +380,12 @@ object GLMFrm: TGLMFrm BorderSpacing.Right = 8 Images = MainDataModule.ImageList ImageIndex = 1 - OnClick = RepDepInBtnClick + OnClick = ReptDepInBtnClick Spacing = 0 TabOrder = 2 end object ReptDepOutBtn: TBitBtn - AnchorSideTop.Control = RepDepInBtn + AnchorSideTop.Control = ReptDepInBtn AnchorSideTop.Side = asrBottom AnchorSideRight.Control = Panel8 AnchorSideRight.Side = asrBottom @@ -421,7 +407,7 @@ object GLMFrm: TGLMFrm AnchorSideLeft.Side = asrBottom AnchorSideTop.Control = Label7 AnchorSideTop.Side = asrBottom - AnchorSideRight.Control = RepDepInBtn + AnchorSideRight.Control = ReptDepInBtn AnchorSideBottom.Control = Panel8 AnchorSideBottom.Side = asrBottom Left = 60 @@ -433,6 +419,7 @@ object GLMFrm: TGLMFrm BorderSpacing.Top = 2 BorderSpacing.Right = 8 ItemHeight = 0 + OnSelectionChange = ContDepCodeSelectionChange TabOrder = 1 end object ReptDepCode: TListBox @@ -447,6 +434,7 @@ object GLMFrm: TGLMFrm Anchors = [akTop, akLeft, akBottom] BorderSpacing.Left = 8 ItemHeight = 0 + OnSelectionChange = ContDepCodeSelectionChange TabOrder = 0 end end @@ -495,6 +483,7 @@ object GLMFrm: TGLMFrm BorderSpacing.Top = 2 ItemHeight = 0 MultiSelect = True + OnSelectionChange = ContDepCodeSelectionChange TabOrder = 0 end end @@ -565,6 +554,7 @@ object GLMFrm: TGLMFrm BorderSpacing.Right = 8 ItemHeight = 0 OnClick = FixedListClick + OnSelectionChange = ContDepCodeSelectionChange TabOrder = 2 end object FixedIndepCode: TListBox @@ -579,6 +569,7 @@ object GLMFrm: TGLMFrm Width = 50 Anchors = [akTop, akRight, akBottom] ItemHeight = 0 + OnSelectionChange = ContDepCodeSelectionChange TabOrder = 3 end object FixedIndepInBtn: TBitBtn @@ -650,6 +641,7 @@ object GLMFrm: TGLMFrm BorderSpacing.Right = 8 ItemHeight = 0 OnClick = RandomListClick + OnSelectionChange = ContDepCodeSelectionChange TabOrder = 2 end object RndIndepCode: TListBox @@ -664,6 +656,7 @@ object GLMFrm: TGLMFrm Width = 50 Anchors = [akTop, akRight, akBottom] ItemHeight = 0 + OnSelectionChange = ContDepCodeSelectionChange TabOrder = 3 end object RndIndepInBtn: TBitBtn @@ -735,6 +728,7 @@ object GLMFrm: TGLMFrm BorderSpacing.Right = 8 ItemHeight = 0 OnClick = CovariateListClick + OnSelectionChange = ContDepCodeSelectionChange TabOrder = 2 end object CovariateCode: TListBox @@ -749,6 +743,7 @@ object GLMFrm: TGLMFrm Width = 50 Anchors = [akTop, akRight, akBottom] ItemHeight = 0 + OnSelectionChange = ContDepCodeSelectionChange TabOrder = 3 end object CovInBtn: TBitBtn @@ -820,6 +815,7 @@ object GLMFrm: TGLMFrm BorderSpacing.Right = 8 ItemHeight = 0 OnClick = RepTrtListClick + OnSelectionChange = ContDepCodeSelectionChange TabOrder = 0 end object RepTrtCode: TListBox @@ -834,6 +830,7 @@ object GLMFrm: TGLMFrm Width = 50 Anchors = [akTop, akRight, akBottom] ItemHeight = 0 + OnSelectionChange = ContDepCodeSelectionChange TabOrder = 1 end object Bevel2: TBevel @@ -896,11 +893,11 @@ object GLMFrm: TGLMFrm end object Label11: TLabel AnchorSideLeft.Control = InterDefList - AnchorSideTop.Control = InterDefList + AnchorSideTop.Control = EndDefBtn AnchorSideTop.Side = asrBottom Left = 20 Height = 15 - Top = 138 + Top = 165 Width = 141 BorderSpacing.Top = 8 Caption = 'List of Defined Interactions' @@ -908,14 +905,14 @@ object GLMFrm: TGLMFrm end object EndDefBtn: TButton AnchorSideLeft.Control = InterDefList - AnchorSideTop.Control = Label11 + AnchorSideTop.Control = InterDefList AnchorSideTop.Side = asrBottom Left = 20 Height = 25 - Top = 161 + Top = 132 Width = 195 AutoSize = True - BorderSpacing.Top = 8 + BorderSpacing.Top = 2 BorderSpacing.Right = 8 Caption = 'End Definititon of an Interaction' OnClick = EndDefBtnClick @@ -923,18 +920,18 @@ object GLMFrm: TGLMFrm end object InteractList: TListBox AnchorSideLeft.Control = InterDefList - AnchorSideTop.Control = EndDefBtn + AnchorSideTop.Control = Label11 AnchorSideTop.Side = asrBottom AnchorSideRight.Control = Panel12 AnchorSideRight.Side = asrBottom AnchorSideBottom.Control = Panel12 AnchorSideBottom.Side = asrBottom Left = 20 - Height = 135 - Top = 194 + Height = 147 + Top = 182 Width = 232 Anchors = [akTop, akLeft, akRight, akBottom] - BorderSpacing.Top = 8 + BorderSpacing.Top = 2 BorderSpacing.Right = 8 ItemHeight = 0 TabOrder = 3 @@ -1095,7 +1092,7 @@ object GLMFrm: TGLMFrm BevelOuter = bvNone ClientHeight = 25 ClientWidth = 862 - TabOrder = 7 + TabOrder = 6 object ShowModelBtn: TButton AnchorSideLeft.Control = Panel14 AnchorSideTop.Control = Panel14 diff --git a/applications/lazstats/source/forms/analysis/comparisons/glmunit.pas b/applications/lazstats/source/forms/analysis/comparisons/glmunit.pas index a1aff31ec..de48b6a10 100644 --- a/applications/lazstats/source/forms/analysis/comparisons/glmunit.pas +++ b/applications/lazstats/source/forms/analysis/comparisons/glmunit.pas @@ -1,3 +1,9 @@ +// Data file for testing: anova2.laz +// - Row, Col --> Fixed effect independent variables +// - Cov1, Col2 --> Covariates (continuous) +// - X --> Continuouse dependent variables +// - Begin definition of an interaction, click Row, Col, end definition + unit GLMUnit; {$mode objfpc}{$H+} @@ -42,7 +48,7 @@ type ContDepOutBtn: TBitBtn; CatDepInBtn: TBitBtn; CatDepOutBtn: TBitBtn; - RepDepInBtn: TBitBtn; + ReptDepInBtn: TBitBtn; ReptDepOutBtn: TBitBtn; FixedIndepInBtn: TBitBtn; FixedIndepOutBtn: TBitBtn; @@ -55,9 +61,8 @@ type CovariateCode: TListBox; RepTrtCode: TListBox; ResetBtn: TButton; - CancelBtn: TButton; ComputeBtn: TButton; - ReturnBtn: TButton; + CloseBtn: TButton; DescChk: TCheckBox; CorsChk: TCheckBox; Label12: TLabel; @@ -93,6 +98,7 @@ type procedure CatDepInBtnClick(Sender: TObject); procedure CatDepOutBtnClick(Sender: TObject); procedure ComputeBtnClick(Sender: TObject); + procedure ContDepCodeSelectionChange(Sender: TObject; User: boolean); procedure ContDepInBtnClick(Sender: TObject); procedure ContDepOutBtnClick(Sender: TObject); procedure CovariateListClick(Sender: TObject); @@ -108,7 +114,7 @@ type procedure HelpBtnClick(Sender: TObject); procedure Panel9Resize(Sender: TObject); procedure RandomListClick(Sender: TObject); - procedure RepDepInBtnClick(Sender: TObject); + procedure ReptDepInBtnClick(Sender: TObject); procedure ReptDepOutBtnClick(Sender: TObject); procedure RepTrtListClick(Sender: TObject); procedure ResetBtnClick(Sender: TObject); @@ -185,18 +191,19 @@ type procedure AllocateGridMem; procedure DeallocateGridMem; procedure DeallocateIDMem; - procedure DummyCodes(min : integer; max : integer; VAR CodePattern : IntDyneMat); - procedure EffectCodes(min : integer; max : integer; VAR CodePattern : IntDyneMat); - procedure OrthogCodes(min : integer; max : integer; VAR CodePattern : IntDyneMat); - procedure RegAnal(Nentered : integer); + procedure DummyCodes(min, max: integer; const CodePattern: IntDyneMat); + procedure EffectCodes(min, max: integer; const CodePattern: IntDyneMat); + procedure OrthogCodes(min, max: integer; const CodePattern: IntDyneMat); + procedure RegAnal(Nentered: integer; AReport: TStrings); procedure PartIEntry; procedure PartIIEntry; - procedure ModelIAnalysis; + procedure ModelIAnalysis(AReport: TStrings); procedure ModelIIAnalysis; - procedure ModelIIIAnalysis; + procedure ModelIIIAnalysis(AReport: TStrings); function CntIntActVecs(linestr : string) : integer; procedure GenInterVecs(linestr : string); procedure CanCor(NLeft : integer; NRight : integer; GridPlace : IntDyneVec); + procedure UpdateBtnStates; public { public declarations } @@ -208,7 +215,8 @@ var implementation uses - Math; + Math, + Utils; { TGLMFrm } @@ -258,42 +266,63 @@ end; procedure TGLMFrm.RndIndepInBtnClick(Sender: TObject); var - index : integer; - codestr : string; - + i: integer; + codestr: string; begin - index := VarList.ItemIndex; - if index >= 0 then + i := 0; + while i < VarList.Items.Count do + begin + if VarList.Selected[i] then begin - RandomList.Items.Add(VarList.Items.Strings[index]); - VarList.Items.Delete(index); - NRndIndep := NRndIndep + 1; - codestr := format('IR%d',[NRndIndep]); - RndIndepCode.Items.Add(codestr); - IndOrderBox.Items.Add(codestr); - RndIndepOutBtn.Enabled := true; - end; + RandomList.Items.Add(VarList.Items[i]); + VarList.Items.Delete(i); + NRndIndep := NRndIndep + 1; + codestr := Format('IR%d', [NRndIndep]); + RndIndepCode.Items.Add(codestr); + IndOrderBox.Items.Add(codestr); + i := 0; + end + else + i := i + 1; + end; + UpdateBtnStates; end; + (* +var + index: integer; + codestr: string; +begin + index := VarList.ItemIndex; + if index > -1 then + begin + RandomList.Items.Add(VarList.Items[index]); + VarList.Items.Delete(index); + NRndIndep := NRndIndep + 1; + codestr := format('IR%d',[NRndIndep]); + RndIndepCode.Items.Add(codestr); + IndOrderBox.Items.Add(codestr); + end; +end; + *) procedure TGLMFrm.RndIndepOutBtnClick(Sender: TObject); var - i, index : integer; - cellstring : string; - + i, index: integer; + cellstring: string; begin - index := RandomList.ItemIndex; - if index >= 0 then - begin - VarList.Items.Add(RandomList.Items.Strings[index]); - RandomList.Items.Delete(index); - cellstring := RndIndepCode.Items.Strings[index]; - RndIndepCode.Items.Delete(index); - for i := 0 to IndOrderBox.Items.Count - 1 do - if cellstring = IndOrderBox.Items.Strings[i] then - IndOrderBox.Items.Delete(i); - NRndIndep := NRndIndep - 1; - if RandomList.ItemIndex < 0 then RndIndepOutBtn.Enabled := false; - end; + index := RandomList.ItemIndex; + if index > -1 then + begin + VarList.Items.Add(RandomList.Items[index]); + RandomList.Items.Delete(index); + cellstring := RndIndepCode.Items[index]; + RndIndepCode.Items.Delete(index); + for i := IndOrderBox.Items.Count - 1 downto 0 do + if cellstring = IndOrderBox.Items.Strings[i] then + IndOrderBox.Items.Delete(i); + NRndIndep := NRndIndep - 1; + end; + UpdateBtnStates; end; procedure TGLMFrm.ShowModelBtnClick(Sender: TObject); @@ -406,19 +435,16 @@ procedure TGLMFrm.FormActivate(Sender: TObject); var w: Integer; begin - w := MaxValue([HelpBtn.Width, ResetBtn.Width, CancelBtn.Width, ComputeBtn.Width, ReturnBtn.Width]); + w := MaxValue([HelpBtn.Width, ResetBtn.Width, ComputeBtn.Width, CloseBtn.Width]); HelpBtn.Constraints.MinWidth := w; ResetBtn.Constraints.MinWidth := w; - CancelBtn.Constraints.MinWidth := w; ComputeBtn.Constraints.MinWidth := w; - ReturnBtn.Constraints.MinWidth := w; + CloseBtn.Constraints.MinWidth := w; end; procedure TGLMFrm.FormCreate(Sender: TObject); begin Assert(OS3MainFrm <> nil); - if OutputFrm = nil then - Application.CreateForm(TOutputFrm, OutputFrm); if DictionaryFrm = nil then Application.CreateForm(TDictionaryFrm, DictionaryFrm); end; @@ -432,7 +458,7 @@ procedure TGLMFrm.HelpBtnClick(Sender: TObject); begin if ContextHelpForm = nil then Application.CreateForm(TContextHelpForm, ContextHelpForm); - ContextHelpForm.HelpMessage((Sender as TButton).tag); + ContextHelpForm.HelpMessage((Sender as TButton).Tag); end; procedure TGLMFrm.RandomListClick(Sender: TObject); @@ -446,53 +472,52 @@ begin end; end; -procedure TGLMFrm.RepDepInBtnClick(Sender: TObject); +procedure TGLMFrm.ReptDepInBtnClick(Sender: TObject); var - index, i : integer; - codestr : string; - + i: integer; + codestr: string; begin - index := VarList.Items.Count; - i := 0; - while i < index do + i := 0; + while i < VarList.Items.Count do + begin + if VarList.Selected[i] then begin - if (VarList.Selected[i]) then - begin - RepeatList.Items.Add(VarList.Items.Strings[i]); - VarList.Items.Delete(i); - NReptDep := NReptDep + 1; - codestr := format('DR%d',[NReptDep]); - if NReptDep = 1 then - begin - ReptDepCode.Items.Add(codestr); - codestr := format('IP%d',[NReptDep]); - IndOrderBox.Items.Add(codestr); - codestr := format('IR%d',[NReptDep]); - IndOrderBox.Items.Add(codestr); - RepTrtCode.Items.Add(codestr); - codestr := format('Rep.Trt.%d',[NReptDep]); - RepTrtList.Items.Add(codestr); - end; - index := index - 1; - i := 0; - end - else i := i + 1; - end; - ReptDepOutBtn.Enabled := true; + RepeatList.Items.Add(VarList.Items[i]); + VarList.Items.Delete(i); + NReptDep := NReptDep + 1; + codestr := Format('DR%d', [NReptDep]); + if NReptDep = 1 then + begin + ReptDepCode.Items.Add(codestr); + codestr := Format('IP%d', [NReptDep]); + IndOrderBox.Items.Add(codestr); + codestr := Format('IR%d', [NReptDep]); + IndOrderBox.Items.Add(codestr); + RepTrtCode.Items.Add(codestr); + codestr := Format('Rep.Trt.%d', [NReptDep]); + RepTrtList.Items.Add(codestr); + end; + i := 0; + end + else + i := i + 1; + end; + UpdateBtnStates; end; procedure TGLMFrm.ReptDepOutBtnClick(Sender: TObject); -VAR index : integer; +var + index: integer; begin - index := RepeatList.ItemIndex; - if index >= 0 then - begin - VarList.Items.Add(RepeatList.Items.Strings[index]); - RepeatList.Items.Delete(index); - ReptDepCode.Items.Delete(index); - NReptDep := NReptDep - 1; - if RepeatList.ItemIndex < 0 then ReptDepOutBtn.Enabled := false; - end; + index := RepeatList.ItemIndex; + if index > -1 then + begin + VarList.Items.Add(RepeatList.Items[index]); + RepeatList.Items.Delete(index); + ReptDepCode.Items.Delete(index); + NReptDep := NReptDep - 1; + end; + UpdateBtnStates; end; procedure TGLMFrm.RepTrtListClick(Sender: TObject); @@ -508,590 +533,631 @@ end; procedure TGLMFrm.ContDepInBtnClick(Sender: TObject); var - index : integer; - codestr : string; - + index: integer; + codestr: string; begin - index := VarList.ItemIndex; - if index >= 0 then - begin - DepContList.Items.Add(VarList.Items.Strings[index]); - VarList.Items.Delete(index); - ContDepOutBtn.Enabled := true; - NContDep := NContDep + 1; - codestr := format('DC%d',[NContDep]); - ContDepCode.Items.Add(codestr); - end; + index := VarList.ItemIndex; + if index > -1 then + begin + DepContList.Items.Add(VarList.Items[index]); + VarList.Items.Delete(index); + NContDep := NContDep + 1; + codestr := Format('DC%d',[NContDep]); + ContDepCode.Items.Add(codestr); + end; + UpdateBtnStates; +end; + +procedure TGLMFrm.ContDepOutBtnClick(Sender: TObject); +var + index: integer; +begin + index := DepContList.ItemIndex; + if index > -1 then + begin + VarList.Items.Add(DepContList.Items[index]); + DepContList.Items.Delete(index); + ContDepCode.Items.Delete(index); + NContDep := NContDep - 1; + end; + UpdateBtnStates; end; procedure TGLMFrm.CatDepInBtnClick(Sender: TObject); var - index : integer; - codestr : string; - + index: integer; + codestr: string; begin - index := VarList.ItemIndex; - if index >= 0 then - begin - DepCatList.Items.Add(VarList.Items.Strings[index]); - VarList.Items.Delete(index); - NCatDep := NCatDep + 1; - codestr := format('DF%d',[NCatDep]); - CatDepCode.Items.Add(codestr); - CatDepOutBtn.Enabled := true; - end; + index := VarList.ItemIndex; + if index > -1 then + begin + DepCatList.Items.Add(VarList.Items[index]); + VarList.Items.Delete(index); + NCatDep := NCatDep + 1; + codestr := format('DF%d',[NCatDep]); + CatDepCode.Items.Add(codestr); + end; + UpdateBtnStates; end; procedure TGLMFrm.CatDepOutBtnClick(Sender: TObject); -VAR index : integer; +var + index: integer; begin - index := DepCatList.ItemIndex; - if index >= 0 then - begin - VarList.Items.Add(DepCatList.Items.Strings[index]); - DepCatList.Items.Delete(index); - CatDepCode.Items.Delete(index); - NCatDep := NCatDep - 1; - if DepCatList.ItemIndex < 0 then CatDepOutBtn.Enabled := false; - end; + index := DepCatList.ItemIndex; + if index > -1 then + begin + VarList.Items.Add(DepCatList.Items[index]); + DepCatList.Items.Delete(index); + CatDepCode.Items.Delete(index); + NCatDep := NCatDep - 1; + end; + UpdateBtnStates; end; procedure TGLMFrm.ComputeBtnClick(Sender: TObject); var - i, j : integer; // no. of variables in the analysis - cellstring : string; - + i, j: integer; // no. of variables in the analysis + cellstring: string; + lReport: TStrings; begin - if (NContDep > 0) and (NReptDep > 0) then - begin - ShowMessage('ERROR! One cannot have both continuous and repeated dependent variables!'); - exit; - end; - gencount := 0; // counter for generated variables - totalobs := 0; // initialize total no. of observations in data grid - AllocateIDMem; // get heap space for arrays - GetIDs; // get var. no.s of dependent and independent variables - novars := GetVarCount; // get total no. of variables to generate - AllocateGridMem; // create data array for values and codes - // Note, the Data Grid first subscript is row (subject) and second the var. - if (NCatDep > 0) or (NContDep > 1) then model := 2 - else model := 1; // use mult.reg for model 1, canonical reg. for model 2 - if NReptDep > 0 then model := 3; + if (NContDep = 0) and (NCatDep = 0) and (NReptDep = 0) then + begin + MessageDlg('No variables selected.', mtError, [mbOK], 0); + exit; + end; - // This procedure first creates the vectors of dependent variables then the - // vectors for independent variables. A case no. is placed in the first - // column of a data grid followed by the dependent variables and then the - // independent variables. If multiple dependent variables are created, the - // type of analysis is a canonical correlation analysis, otherwise a - // multiple regression analysis. Analyses are performed to obtain both - // Type I SS's and Type II SS's (stepwise addition and unique contribution) + if (NContDep > 0) and (NReptDep > 0) then + begin + MessageDlg('One cannot have both continuous and repeated dependent variables!', mtError, [mbOK], 0); + exit; + end; - // PART I. ENTRY OF DEPENDENT VARIABLES (AND OBSERVATION NO.) - // Place case labels in data grid and for repeated measures, spread out - // the repeated measures over NoCases * No. repeated measures - PartIEntry; + gencount := 0; // counter for generated variables + totalobs := 0; // initialize total no. of observations in data grid + AllocateIDMem; // get heap space for arrays + GetIDs; // get var. no.s of dependent and independent variables + novars := GetVarCount; // get total no. of variables to generate + AllocateGridMem; // create data array for values and codes + // Note, the Data Grid first subscript is row (subject) and second the var. + if (NCatDep > 0) or (NContDep > 1) then + model := 2 + else + model := 1; // use mult.reg for model 1, canonical reg. for model 2 + if NReptDep > 0 then + model := 3; - // PART II. CREATION OF INDEPENDENT VARIABLE VECTORS - // First, if there are repeated measures, generate (n - 1) person vectors - PartIIEntry; + // This procedure first creates the vectors of dependent variables then the + // vectors for independent variables. A case no. is placed in the first + // column of a data grid followed by the dependent variables and then the + // independent variables. If multiple dependent variables are created, the + // type of analysis is a canonical correlation analysis, otherwise a + // multiple regression analysis. Analyses are performed to obtain both + // Type I SS's and Type II SS's (stepwise addition and unique contribution) + // PART I. ENTRY OF DEPENDENT VARIABLES (AND OBSERVATION NO.) + // Place case labels in data grid and for repeated measures, spread out + // the repeated measures over NoCases * No. repeated measures + PartIEntry; + + // PART II. CREATION OF INDEPENDENT VARIABLE VECTORS + // First, if there are repeated measures, generate (n - 1) person vectors + PartIIEntry; + + lReport := TStringList.Create; + try // Now, do the analyses - if model = 1 then ModelIAnalysis; // models with 1 dependent variable - if model = 2 then ModelIIAnalysis; // models with 2 or more dependent var.s - if model = 3 then ModelIIIAnalysis; // Repeated measures designs + case model of + 1: ModelIAnalysis(lReport); // models with 1 dependent variable + 2: ModelIIAnalysis; // models with 2 or more dependent var.s + 3: ModelIIIAnalysis(lReport); // Repeated measures designs + end; // Place generated data into the main form's grid if ShowDesignChk.Checked then begin - if NoVariables < gencount then - begin - j := NoVariables; - for i := j+1 to gencount do - begin - DictionaryFrm.NewVar(j); - end; - end; - OS3MainFrm.DataGrid.RowCount := totalobs+1; - for i := 1 to totalobs do - for j := 1 to gencount do - OS3MainFrm.DataGrid.Cells[j,i] := FloatToStr(DataGrid[i-1,j-1]); - for i := 1 to gencount do - begin - OS3MainFrm.DataGrid.Cells[i,0] := GenLabels[i-1]; - DictionaryFrm.Defaults(Self,i); - DictionaryFrm.DictGrid.Cells[1,i] := GenLabels[i-1]; - end; - for i := 1 to totalobs do - begin - cellstring := format('CASE%d',[i]); - OS3MainFrm.DataGrid.Cells[0,i] := cellstring; - end; - OS3MainFrm.NoCasesEdit.Text := IntToStr(totalobs); - OS3MainFrm.NoVarsEdit.Text := IntToStr(gencount); - NoVariables := gencount; - NoCases := totalobs; - OS3MainFrm.FileNameEdit.Text := ''; + if NoVariables < gencount then + begin + j := NoVariables; + for i := j+1 to gencount do + DictionaryFrm.NewVar(j); + end; + + OS3MainFrm.DataGrid.RowCount := totalobs+1; + + for i := 1 to totalobs do + for j := 1 to gencount do + OS3MainFrm.DataGrid.Cells[j,i] := FloatToStr(DataGrid[i-1,j-1]); + + for i := 1 to gencount do + begin + OS3MainFrm.DataGrid.Cells[i,0] := GenLabels[i-1]; + DictionaryFrm.Defaults(Self,i); + DictionaryFrm.DictGrid.Cells[1,i] := GenLabels[i-1]; + end; + + for i := 1 to totalobs do + begin + cellstring := format('CASE%d',[i]); + OS3MainFrm.DataGrid.Cells[0,i] := cellstring; + end; + + OS3MainFrm.NoCasesEdit.Text := IntToStr(totalobs); + OS3MainFrm.NoVarsEdit.Text := IntToStr(gencount); + NoVariables := gencount; + NoCases := totalobs; + OS3MainFrm.FileNameEdit.Text := ''; end; + DisplayReport(lReport); + + finally + lReport.Free; DeallocateGridMem; // free up heap allocated to data array DeallocateIDMem; // free up heap space + end; end; -procedure TGLMFrm.ContDepOutBtnClick(Sender: TObject); -VAR index : integer; +procedure TGLMFrm.ContDepCodeSelectionChange(Sender: TObject; User: boolean); begin - index := DepContList.ItemIndex; - if index >= 0 then - begin - VarList.Items.Add(DepContList.Items.Strings[index]); - DepContList.Items.Delete(index); - ContDepCode.Items.Delete(index); - NContDep := NContDep - 1; - if DepContList.ItemIndex < 0 then ContDepOutBtn.Enabled := false; - end; + UpdateBtnStates; end; procedure TGLMFrm.CovariateListClick(Sender: TObject); -VAR index : integer; +var + index: integer; begin - if IntDef then + if IntDef then + begin + index := CovariateList.ItemIndex; + if index > -1 then begin - index := CovariateList.ItemIndex; - InterDefList.Items.Add(CovariateCode.Items.Strings[index]); - DefLine := DefLine + 1; // counter for number of terms - 1 + InterDefList.Items.Add(CovariateCode.Items[index]); + DefLine := DefLine + 1; // counter for number of terms - 1 end; + end; end; procedure TGLMFrm.CovInBtnClick(Sender: TObject); var - index : integer; - codestr : string; - + i: integer; + codestr: string; begin - index := VarList.ItemIndex; - if index >= 0 then + i := 0; + while i < VarList.Items.Count do + begin + if VarList.Selected[i] then begin - CovariateList.Items.Add(VarList.Items.Strings[index]); - VarList.Items.Delete(index); - NCovIndep := NCovIndep + 1; - codestr := format('IC%d',[NCovIndep]); - CovariateCode.Items.Add(codestr); - IndOrderBox.Items.Add(codestr); - CovOutBtn.Enabled := true; - end; + CovariateList.Items.Add(VarList.Items[i]); + VarList.Items.Delete(i); + NCovIndep := NCovIndep + 1; + codestr := Format('IC%d', [NCovIndep]); + CovariateCode.Items.Add(codestr); + IndOrderBox.Items.Add(codestr); + i := 0; + end + else + i := i + 1; + end; + UpdateBtnStates; end; - +{ +var + index: integer; + codestr: string; +begin + index := VarList.ItemIndex; + if index > -1 then + begin + CovariateList.Items.Add(VarList.Items[index]); + VarList.Items.Delete(index); + NCovIndep := NCovIndep + 1; + codestr := Format('IC%d', [NCovIndep]); + CovariateCode.Items.Add(codestr); + IndOrderBox.Items.Add(codestr); + end; + UpdateBtnStates; +end; +} procedure TGLMFrm.CovOutBtnClick(Sender: TObject); var - i, index : integer; - cellstring : string; - + i, index: integer; + cellstring: string; begin - index := CovariateList.ItemIndex; - if index >= 0 then - begin - VarList.Items.Add(CovariateList.Items.Strings[index]); - CovariateList.Items.Delete(index); - cellstring := CovariateCode.Items.Strings[index]; - CovariateCode.Items.Delete(index); - for i := 0 to IndOrderBox.Items.Count - 1 do - if cellstring = IndOrderBox.Items.Strings[i] then - IndOrderBox.Items.Delete(i); - NCovIndep := NCovIndep - 1; - if CovariateList.ItemIndex < 0 then CovOutBtn.Enabled := false; - end; + index := CovariateList.ItemIndex; + if index > -1 then + begin + VarList.Items.Add(CovariateList.Items[index]); + CovariateList.Items.Delete(index); + cellstring := CovariateCode.Items[index]; + CovariateCode.Items.Delete(index); + for i := IndOrderBox.Items.Count - 1 downto 0 do + if cellstring = IndOrderBox.Items[i] then + IndOrderBox.Items.Delete(i); + NCovIndep := NCovIndep - 1; + end; + UpdateBtnStates; end; procedure TGLMFrm.EndDefBtnClick(Sender: TObject); var - index : integer; - nolines : integer; - LineStr : string; - + index: integer; + nolines: integer; + LineStr: string; begin - LineStr := ''; - nolines := InterDefList.Items.Count; - if nolines > 0 then + LineStr := ''; + nolines := InterDefList.Items.Count; + if nolines > 0 then + begin + for index := 0 to nolines - 1 do begin - for index := 0 to nolines - 1 do - begin - LineStr := LineStr + InterDefList.Items.Strings[index]; - if index < nolines - 1 then LineStr := LineStr + ' * '; - end; - InteractList.Items.Add(LineStr); - IndOrderBox.Items.Add(LineStr); - NoInterDefs := NoInterDefs + 1; + LineStr := LineStr + InterDefList.Items.Strings[index]; + if index < nolines - 1 then LineStr := LineStr + ' * '; end; - InterDefList.Clear; + InteractList.Items.Add(LineStr); + IndOrderBox.Items.Add(LineStr); + NoInterDefs := NoInterDefs + 1; + end; + InterDefList.Clear; end; procedure TGLMFrm.FixedIndepInBtnClick(Sender: TObject); var - index, i : integer; - codestr : string; - + i: integer; + codestr: string; begin - index := VarList.Items.Count; - i := 0; - while i < index do + i := 0; + while i < VarList.Items.Count do + begin + if VarList.Selected[i] then begin - if (VarList.Selected[i]) then - begin - FixedList.Items.Add(VarList.Items.Strings[i]); - VarList.Items.Delete(i); - NFixedIndep := NFixedIndep + 1; - codestr := format('IF%d',[NFixedIndep]); - FixedIndepCode.Items.Add(codestr); - IndOrderBox.Items.Add(codestr); - index := index - 1; - i := 0; - end - else i := i + 1; - end; - FixedIndepOutBtn.Enabled := true; + FixedList.Items.Add(VarList.Items[i]); + VarList.Items.Delete(i); + NFixedIndep := NFixedIndep + 1; + codestr := Format('IF%d', [NFixedIndep]); + FixedIndepCode.Items.Add(codestr); + IndOrderBox.Items.Add(codestr); + i := 0; + end + else + i := i + 1; + end; + UpdateBtnStates; end; procedure TGLMFrm.FixedIndepOutBtnClick(Sender: TObject); var - i, index : integer; - cellstring : string; - + i, index: integer; + cellstring: string; begin - index := FixedList.ItemIndex; - if index >= 0 then - begin - VarList.Items.Add(FixedList.Items.Strings[index]); - FixedList.Items.Delete(index); - cellstring := FixedIndepCode.Items.Strings[index]; - FixedIndepCode.Items.Delete(index); - NFixedIndep := NFixedIndep - 1; - for i := 0 to IndOrderBox.Items.Count - 1 do - if IndOrderBox.Items.Strings[i] = cellstring then - IndOrderBox.Items.Delete(i); - if FixedList.ItemIndex < 0 then FixedIndepOutBtn.Enabled := false; - end; + index := FixedList.ItemIndex; + if index > -1 then + begin + VarList.Items.Add(FixedList.Items[index]); + FixedList.Items.Delete(index); + cellstring := FixedIndepCode.Items[index]; + FixedIndepCode.Items.Delete(index); + NFixedIndep := NFixedIndep - 1; + for i := IndOrderBox.Items.Count - 1 downto 0 do + if IndOrderBox.Items.Strings[i] = cellstring then + IndOrderBox.Items.Delete(i); + end; + UpdateBtnStates; end; procedure TGLMFrm.FixedListClick(Sender: TObject); -VAR index : integer; +var + index: integer; begin - if IntDef then - begin - index := FixedList.ItemIndex; - InterDefList.Items.Add(FixedIndepCode.Items.Strings[index]); - DefLine := DefLine + 1; // counter for number of terms + if IntDef then + begin + index := FixedList.ItemIndex; + if index > -1 then begin + InterDefList.Items.Add(FixedIndepCode.Items[index]); + DefLine := DefLine + 1; // counter for number of terms end; + end; end; procedure TGLMFrm.AllocateIDMem; begin - if NContDep > 0 then - begin - SetLength(ContDepID,NContDep); - SetLength(ContDepPos,NContDep); - end; - if NCatDep > 0 then - begin - SetLength(CatDepID,NCatDep); - SetLength(CatDepPos,NCatDep); - SetLength(NFixVecDep,NCatDep); - end; - if NReptDep > 0 then - begin - SetLength(ReptDepID,NReptDep); - SetLength(ReptDepPos,NReptDep); - SetLength(ReptIndepPos,NoCases); - SetLength(ReptTrtPos,NReptDep); - end; - if NFixedIndep > 0 then - begin - SetLength(FixedIndepID,NFixedIndep); - SetLength(FixedIndepPos,NFixedIndep); - SetLength(NFixVecIndep,NFixedIndep); - end; - if NRndIndep > 0 then - begin - SetLength(RndIndepID,NRndIndep); - SetLength(RndIndepPos,NRndIndep); - SetLength(NRndVecIndep,NRndIndep); - end; - if NCovIndep > 0 then - begin - SetLength(CovIndepID,NCovIndep); - SetLength(CovIndepPos,NCovIndep); - end; - if NoInterDefs > 0 then - begin - SetLength(NInteractVecs,NoInterDefs); - SetLength(InteractPos,NoInterDefs); - end; + if NContDep > 0 then + begin + SetLength(ContDepID, NContDep); + SetLength(ContDepPos, NContDep); + end; + + if NCatDep > 0 then + begin + SetLength(CatDepID, NCatDep); + SetLength(CatDepPos, NCatDep); + SetLength(NFixVecDep, NCatDep); + end; + + if NReptDep > 0 then + begin + SetLength(ReptDepID, NReptDep); + SetLength(ReptDepPos, NReptDep); + SetLength(ReptIndepPos, NoCases); + SetLength(ReptTrtPos, NReptDep); + end; + + if NFixedIndep > 0 then + begin + SetLength(FixedIndepID, NFixedIndep); + SetLength(FixedIndepPos, NFixedIndep); + SetLength(NFixVecIndep, NFixedIndep); + end; + + if NRndIndep > 0 then + begin + SetLength(RndIndepID, NRndIndep); + SetLength(RndIndepPos, NRndIndep); + SetLength(NRndVecIndep, NRndIndep); + end; + + if NCovIndep > 0 then + begin + SetLength(CovIndepID, NCovIndep); + SetLength(CovIndepPos, NCovIndep); + end; + + if NoInterDefs > 0 then + begin + SetLength(NInteractVecs, NoInterDefs); + SetLength(InteractPos, NoInterDefs); + end; end; procedure TGLMFrm.GetIDs; var - cellstring : string; - i, j : integer; - + cellstring: string; + i, j: integer; begin - if NContDep > 0 then + if NContDep > 0 then + begin + for i := 0 to NContDep - 1 do begin - for i := 0 to NContDep - 1 do - begin - cellstring := DepContList.Items.Strings[i]; - for j := 1 to NoVariables do - begin - if cellstring = OS3MainFrm.DataGrid.Cells[j,0] then - ContDepID[i] := j; - end; - end; + cellstring := DepContList.Items[i]; + for j := 1 to NoVariables do + if cellstring = OS3MainFrm.DataGrid.Cells[j,0] then + ContDepID[i] := j; end; - if NCatDep > 0 then + end; + + if NCatDep > 0 then + begin + for i := 0 to NCatDep - 1 do begin - for i := 0 to NCatDep - 1 do - begin - cellstring := DepCatList.Items.Strings[i]; - for j := 1 to NoVariables do - begin - if cellstring = OS3MainFrm.DataGrid.Cells[j,0] then - CatDepID[i] := j; - end; - end; + cellstring := DepCatList.Items[i]; + for j := 1 to NoVariables do + if cellstring = OS3MainFrm.DataGrid.Cells[j,0] then + CatDepID[i] := j; end; - if NReptDep > 0 then + end; + + if NReptDep > 0 then + begin + for i := 0 to NReptDep - 1 do begin - for i := 0 to NReptDep - 1 do - begin - cellstring := RepeatList.Items.Strings[i]; - for j := 1 to NoVariables do - begin - if cellstring = OS3MainFrm.DataGrid.Cells[j,0] then - ReptDepID[i] := j; - end; - end; + cellstring := RepeatList.Items[i]; + for j := 1 to NoVariables do + if cellstring = OS3MainFrm.DataGrid.Cells[j,0] then + ReptDepID[i] := j; end; - if NFixedIndep > 0 then + end; + + if NFixedIndep > 0 then + begin + for i := 0 to NFixedIndep - 1 do begin - for i := 0 to NFixedIndep - 1 do - begin - cellstring := FixedList.Items.Strings[i]; - for j := 1 to NoVariables do - begin - if cellstring = OS3MainFrm.DataGrid.Cells[j,0] then - FixedIndepID[i] := j; - end; - end; + cellstring := FixedList.Items[i]; + for j := 1 to NoVariables do + if cellstring = OS3MainFrm.DataGrid.Cells[j,0] then + FixedIndepID[i] := j; end; - if NRndIndep > 0 then + end; + + if NRndIndep > 0 then + begin + for i := 0 to NRndIndep - 1 do begin - for i := 0 to NRndIndep - 1 do - begin - cellstring := RandomList.Items.Strings[i]; - for j := 1 to NoVariables do - begin - if cellstring = OS3MainFrm.DataGrid.Cells[j,0] then - RndIndepID[i] := j; - end; - end; - end; - if NCovIndep > 0 then + cellstring := RandomList.Items[i]; + for j := 1 to NoVariables do + if cellstring = OS3MainFrm.DataGrid.Cells[j,0] then + RndIndepID[i] := j; + end; + end; + + if NCovIndep > 0 then + begin + for i := 0 to NCovIndep - 1 do begin - for i := 0 to NCovIndep - 1 do - begin - cellstring := CovariateList.Items.Strings[i]; - for j := 1 to NoVariables do - begin - if cellstring = OS3MainFrm.DataGrid.Cells[j,0] then - CovIndepID[i] := j; - end; - end; + cellstring := CovariateList.Items[i]; + for j := 1 to NoVariables do + if cellstring = OS3MainFrm.DataGrid.Cells[j,0] then + CovIndepID[i] := j; end; + end; end; function TGLMFrm.GetVarCount: integer; var - count, i, j, col, nvectors : integer; - min, max : integer; // use to get no. of coding vectors for categorical var.s - group : integer; - linestr : string; - + count, i, j, col, nvectors: integer; + min, max: integer; // use to get no. of coding vectors for categorical var.s + group: integer; + linestr: string; begin - count := 1; // one column for case id's - count := count + NContDep + NCovIndep; // sum of continuous variables - if NReptDep > 0 then count := count + 1; // one col. for repeated dep. measure - // plus person vectors for repeated measures (independent predictors) - if NReptDep > 0 then count := count + (NoCases - 1); // person vectors - if NReptDep > 0 then count := count + (NreptDep - 1); // repeated treatment vectors - if NCatDep > 0 then // calculate min and max for each var. to get no. of vectors - begin - for i := 0 to NCatDep - 1 do - begin - col := CatDepID[i]; - min := round(StrToFloat(OS3MainFrm.DataGrid.Cells[col,1])); - max := min; - for j := 1 to NoCases do - begin - group := round(StrToFLoat(OS3MainFrm.DataGrid.Cells[col,j])); - if group < min then min := group; - if group > max then max := group; - end; - count := count + (max - min); // 1 less than the no. of groups - NFixVecDep[i] := count; - end; - end; + count := 1; // one column for case id's + count := count + NContDep + NCovIndep; // sum of continuous variables + if NReptDep > 0 then count := count + 1; // one col. for repeated dep. measure + // plus person vectors for repeated measures (independent predictors) + if NReptDep > 0 then count := count + (NoCases - 1); // person vectors + if NReptDep > 0 then count := count + (NreptDep - 1); // repeated treatment vectors - if NFixedIndep > 0 then // add no. of vectors to count + // calculate min and max for each var. to get no. of vectors + if NCatDep > 0 then + begin + for i := 0 to NCatDep - 1 do begin - for i := 0 to NFixedIndep - 1 do - begin - col := FixedIndepID[i]; - min := round(StrToFloat(OS3MainFrm.DataGrid.Cells[col,1])); - max := min; - for j := 1 to NoCases do - begin - group := round(StrToFloat(OS3MainFrm.DataGrid.Cells[col,j])); - if group < min then min := group; - if group > max then max := group; - end; - count := count + (max - min); // 1 less than the no. of groups - NFixVecIndep[i] := max - min; - end; + col := CatDepID[i]; + min := round(StrToFloat(OS3MainFrm.DataGrid.Cells[col,1])); + max := min; + for j := 1 to NoCases do + begin + group := round(StrToFLoat(OS3MainFrm.DataGrid.Cells[col,j])); + if group < min then min := group; + if group > max then max := group; + end; + count := count + (max - min); // 1 less than the no. of groups + NFixVecDep[i] := count; end; + end; - if NRndIndep > 0 then // add no. of vectors to count + // add no. of vectors to count + if NFixedIndep > 0 then + begin + for i := 0 to NFixedIndep - 1 do begin - for i := 0 to NRndIndep - 1 do - begin - col := RndIndepID[i]; - min := round(StrToFloat(OS3MainFrm.DataGrid.Cells[col,1])); - max := min; - for j := 1 to NoCases do - begin - group := round(StrToFloat(OS3MainFrm.DataGrid.Cells[col,j])); - if group < min then min := group; - if group > max then max := group; - end; - count := count + (max - min); // 1 less than the no. of groups - NRndVecIndep[i] := max - min; - end; + col := FixedIndepID[i]; + min := round(StrToFloat(OS3MainFrm.DataGrid.Cells[col,1])); + max := min; + for j := 1 to NoCases do + begin + group := round(StrToFloat(OS3MainFrm.DataGrid.Cells[col,j])); + if group < min then min := group; + if group > max then max := group; + end; + count := count + (max - min); // 1 less than the no. of groups + NFixVecIndep[i] := max - min; end; + end; - if NoInterDefs > 0 then // get no. of vectors for each interaction + // add no. of vectors to count + if NRndIndep > 0 then + begin + for i := 0 to NRndIndep - 1 do begin - for i := 0 to NoInterDefs - 1 do - begin - linestr := InterActList.Items.Strings[i]; - // parse the line for variable definitions and get no. of columns - // and vectors for the products of these variables - nvectors := CntIntActVecs(linestr); - NInteractVecs[i] := nvectors; - count := count + nvectors; - end; + col := RndIndepID[i]; + min := round(StrToFloat(OS3MainFrm.DataGrid.Cells[col,1])); + max := min; + for j := 1 to NoCases do + begin + group := round(StrToFloat(OS3MainFrm.DataGrid.Cells[col,j])); + if group < min then min := group; + if group > max then max := group; + end; + count := count + (max - min); // 1 less than the no. of groups + NRndVecIndep[i] := max - min; end; - Result := count; + end; + + // get no. of vectors for each interaction + if NoInterDefs > 0 then + begin + for i := 0 to NoInterDefs - 1 do + begin + linestr := InterActList.Items.Strings[i]; + // parse the line for variable definitions and get no. of columns + // and vectors for the products of these variables + nvectors := CntIntActVecs(linestr); + NInteractVecs[i] := nvectors; + count := count + nvectors; + end; + end; + + Result := count; end; procedure TGLMFrm.AllocateGridMem; var - norows : integer; - + norows: integer; begin - if NReptDep > 0 then norows := NoCases * NReptDep - else norows := NoCases; - SetLength(DataGrid,norows+1,novars+4); // grid data for generated data - SetLength(GenLabels,novars+4); // column labels of new data grid - SetLength(Labels,novars+4); // labels of variables entered into analysis - SetLength(ColSelected,novars+4); // datagrid columns selected for analysis + if NReptDep > 0 then + norows := NoCases * NReptDep + else + norows := NoCases; + SetLength(DataGrid, norows+1, novars+4); // grid data for generated data + SetLength(GenLabels, novars+4); // column labels of new data grid + SetLength(Labels, novars+4); // labels of variables entered into analysis + SetLength(ColSelected, novars+4); // datagrid columns selected for analysis end; procedure TGLMFrm.DeallocateGridMem; begin - ColSelected := nil; - Labels := nil; - GenLabels := nil; - DataGrid := nil; + ColSelected := nil; + Labels := nil; + GenLabels := nil; + DataGrid := nil; end; procedure TGLMFrm.DeallocateIDMem; begin - InteractPos := nil; - NInteractVecs := nil; - CovIndepPos := nil; - CovIndepID := nil; - NRndVecIndep := nil; - RndIndepPos := nil; - RndIndepID := nil; - NFixVecIndep := nil; - FixedIndepPos := nil; - FixedIndepID := nil; - ReptTrtPos := nil; - ReptIndepPos := nil; - ReptDepPos := nil; - ReptDepID := nil; - NFixVecDep := nil; - CatDepPos := nil; - CatDepID := nil; - ContDepPos := nil; - ContDepID := nil; + InteractPos := nil; + NInteractVecs := nil; + CovIndepPos := nil; + CovIndepID := nil; + NRndVecIndep := nil; + RndIndepPos := nil; + RndIndepID := nil; + NFixVecIndep := nil; + FixedIndepPos := nil; + FixedIndepID := nil; + ReptTrtPos := nil; + ReptIndepPos := nil; + ReptDepPos := nil; + ReptDepID := nil; + NFixVecDep := nil; + CatDepPos := nil; + CatDepID := nil; + ContDepPos := nil; + ContDepID := nil; end; -procedure TGLMFrm.DummyCodes(min: integer; max: integer; - var CodePattern: IntDyneMat); +procedure TGLMFrm.DummyCodes(min, max: integer; const CodePattern: IntDyneMat); var - ngrps : integer; - vects : integer; - i, j : integer; - + ngrps: integer; + vects: integer; + i, j: integer; begin - ngrps := max - min + 1; - vects := ngrps - 1; + ngrps := max - min + 1; + vects := ngrps - 1; + for j := 1 to vects do + for i := 1 to ngrps do + if i = j then CodePattern[i,j] := 1 else CodePattern[i,j] := 0; +end; + +procedure TGLMFrm.EffectCodes(min, max: integer; const CodePattern: IntDyneMat); +var + ngrps: integer; + vects: integer; + i, j: integer; +begin + ngrps := max - min + 1; + vects := ngrps - 1; + for i := 1 to ngrps do for j := 1 to vects do begin - for i := 1 to ngrps do - begin - if i = j then CodePattern[i,j] := 1 else CodePattern[i,j] := 0; - end; + if i = j then CodePattern[i,j] := 1; + if i = ngrps then CodePattern[i,j] := -1; + if (i <> j) and (i <> ngrps) then CodePattern[i,j] := 0; end; end; -procedure TGLMFrm.EffectCodes(min: integer; max: integer; - var CodePattern: IntDyneMat); +procedure TGLMFrm.OrthogCodes(min, max: integer; const CodePattern: IntDyneMat); var - ngrps : integer; - vects : integer; - i, j : integer; - + ngrps: integer; + vects: integer; + i, j: integer; begin - ngrps := max - min + 1; - vects := ngrps - 1; - for i := 1 to ngrps do + ngrps := max - min + 1; + vects := ngrps - 1; + for i := 1 to ngrps do + for j := 1 to vects do begin - for j := 1 to vects do - begin - if i = j then CodePattern[i,j] := 1; - if i = ngrps then CodePattern[i,j] := -1; - if (i <> j) and (i <> ngrps) then CodePattern[i,j] := 0; - end; - end; -end; - -procedure TGLMFrm.OrthogCodes(min: integer; max: integer; - var CodePattern: IntDyneMat); -var - ngrps : integer; - vects : integer; - i, j : integer; - -begin - ngrps := max - min + 1; - vects := ngrps - 1; - for i := 1 to ngrps do - begin - for j := 1 to vects do - begin - if i <= j then CodePattern[i,j] := 1; - if i-1 = j then CodePattern[i,j] := -j; - if i > j+1 then CodePattern[i,j] := 0; - end; + if i <= j then CodePattern[i,j] := 1; + if i-1 = j then CodePattern[i,j] := -j; + if i > j+1 then CodePattern[i,j] := 0; end; end; @@ -1100,68 +1166,87 @@ begin Bevel3.Constraints.MinHeight := Panel8.Height; end; -procedure TGLMFrm.RegAnal(Nentered: integer); +procedure TGLMFrm.RegAnal(Nentered: integer; AReport: TStrings); var - i, j, nvars, ncases : integer; - title : string; - + i, j, nvars, ncases: integer; + title: string; begin - nvars := Nentered; - ncases := totalobs; - SetLength(rmatrix,nvars+1,nvars+1); - SetLength(indmatrix,nvars-1,nvars-1); - SetLength(rxy,nvars); - SetLength(invmatrix,nvars,nvars); - SetLength(B,nvars); - SetLength(Beta,nvars); - SetLength(means,nvars); - SetLength(Vars,nvars); - SetLength(StdDevs,nvars); - SetLength(workmat,nvars,nvars); + nvars := Nentered; + ncases := totalobs; + SetLength(rmatrix, nvars+1, nvars+1); + SetLength(indmatrix, nvars-1, nvars-1); + SetLength(rxy, nvars); + SetLength(invmatrix, nvars ,nvars); + SetLength(B, nvars); + SetLength(Beta, nvars); + SetLength(means, nvars); + SetLength(Vars, nvars); + SetLength(StdDevs, nvars); + SetLength(workmat, nvars, nvars); - DynCorrelations(nvars,ColSelected,DataGrid,rmatrix,means,vars,StdDevs,ncases,3); - OutputFrm.RichEdit.Clear; + DynCorrelations(nvars, ColSelected, DataGrid, rmatrix, means, vars, StdDevs, ncases, 3); + + AReport.Add(''); + AReport.Add('======================================================================================='); + AReport.Add(''); + + if DescChk.Checked then + begin title := 'Means'; - if DescChk.Checked then DynVectorPrint(means,Nentered,title,Labels,ncases); + DynVectorPrint(means, Nentered, title, Labels, ncases, AReport); + end; + + if CorsChk.Checked then + begin title := 'Correlations'; - if CorsChk.Checked then - MAT_PRINT(rmatrix,Nentered,Nentered,title,Labels,Labels,ncases); - for i := 1 to nvars - 1 do + MatPrint(rmatrix, Nentered, Nentered, title, Labels, Labels, ncases, AReport); + end; + + for i := 1 to nvars - 1 do + begin + rxy[i-1] := rmatrix[i,0]; // r's with dependent var + for j := 1 to nvars - 1 do begin - rxy[i-1] := rmatrix[i,0]; // r's with dependent var - for j := 1 to nvars - 1 do - begin - indmatrix[i-1,j-1] := rmatrix[i,j]; // intercorr.s of indep. var.s - workmat[i-1,j-1] := rmatrix[i,j]; // used to get inverse - end; + indmatrix[i-1,j-1] := rmatrix[i,j]; // intercorr.s of indep. var.s + workmat[i-1,j-1] := rmatrix[i,j]; // used to get inverse end; - SVDinverse(workmat,nvars-1); - // Copy inverse to zero indexed matrix - for i := 1 to nvars-1 do - for j := 1 to nvars-1 do invmatrix[i-1,j-1] := workmat[i-1,j-1]; - title := 'inverse of indep. matrix'; - // get betas and squared multiple correlation - R2 := 0.0; - for i := 1 to nvars-1 do - begin - Beta[i-1] := 0.0; - for j := 1 to nvars-1 do Beta[i-1] := Beta[i-1] + invmatrix[i-1,j-1] * rxy[j-1]; - R2 := R2 + Beta[i-1] * rxy[i-1]; - end; -// outline := format('Squared Multiple Correlation = %6.4f',[R2]); -// OutputFrm.RichEdit.Lines.Add(outline); -// title := 'Standardized regression coefficients'; -// DynVectorPrint(Beta,Nentered-1,title,Labels,ncases); - // get raw coefficients - for i := 1 to nvars - 1 do - begin - if StdDevs[i] > 0.0 then - B[i-1] := Beta[i-1] * (StdDevs[0] / StdDevs[i]) - else B[i-1] := 0.0; - end; -// title := 'Raw regression coefficients'; -// DynVectorPrint(B,Nentered-1,title,Labels,ncases); -// OutputFrm.ShowModal; + end; + SVDinverse(workmat, nvars-1); + + // Copy inverse to zero indexed matrix + for i := 1 to nvars-1 do + for j := 1 to nvars-1 do + invmatrix[i-1,j-1] := workmat[i-1,j-1]; + + title := 'inverse of indep. matrix'; + + // get betas and squared multiple correlation + R2 := 0.0; + for i := 1 to nvars-1 do + begin + Beta[i-1] := 0.0; + for j := 1 to nvars-1 do + Beta[i-1] := Beta[i-1] + invmatrix[i-1,j-1] * rxy[j-1]; + R2 := R2 + Beta[i-1] * rxy[i-1]; + end; + + // outline := format('Squared Multiple Correlation = %6.4f',[R2]); + // OutputFrm.RichEdit.Lines.Add(outline); + // title := 'Standardized regression coefficients'; + // DynVectorPrint(Beta,Nentered-1,title,Labels,ncases); + + // get raw coefficients + for i := 1 to nvars - 1 do + begin + if StdDevs[i] > 0.0 then + B[i-1] := Beta[i-1] * (StdDevs[0] / StdDevs[i]) + else + B[i-1] := 0.0; + end; + + // title := 'Raw regression coefficients'; + // DynVectorPrint(B,Nentered-1,title,Labels,ncases); + // OutputFrm.ShowModal; end; procedure TGLMFrm.PartIEntry; @@ -1451,574 +1536,563 @@ begin codepattern := nil; end; -procedure TGLMFrm.ModelIAnalysis; +procedure TGLMFrm.ModelIAnalysis(AReport: TStrings); var - block, i, j, k, NEntered, index, noblocks, priorentered : integer; - cellstring : string; - labelstr : string; - outline : string; - R, R2Increment, SSx, sum, constant, FullR2 : double; - df1, df2, F, FProbF, StdErrB,OldDF1, PredSS, PredMS : double; - SSt, VarEst, SSres, StdErrEst, AdjR2 : double; - + block, i, j, k, NEntered, index, noblocks, priorentered : integer; + cellstring : string; + labelstr : string; + outline : string; + R, R2Increment, SSx, sum, constant, FullR2 : double; + df1, df2, F, FProbF, StdErrB,OldDF1, PredSS, PredMS : double; + SSt, VarEst, SSres, StdErrEst, AdjR2 : double; begin + NEntered := 0; + OldDF1 := 0.0; + priorentered := 0; + OldR2 := 0; + + // enter the dependent variable first + if NContDep > 0 then + begin + ColSelected[0] := ContDepPos[0]; + Labels[0] := GenLabels[1]; + end + else begin + ColSelected[0] := ReptDepPos[0]; + Labels[0] := GenLabels[1]; + end; + NEntered := NEntered + 1; + + // Enter independent variables as indicated in indorderbox then interactions + // until the total model is analyzed. Then delete each term to get a + // restricted model and compare to the full model. + noblocks := IndOrderBox.Items.Count; + SetLength(TypeISS,noblocks); + SetLength(TypeIISS,noblocks); + SetLength(TypeIMS,noblocks); + SetLength(TypeIIMS,noblocks); + SetLength(TypeIDF1,noblocks); + SetLength(TypeIDF2,noblocks); + SetLength(TypeIIDF1,noblocks); + SetLength(TypeIIDF2,noblocks); + SetLength(TypeIF,noblocks); + SetLength(TypeIProb,noblocks); + SetLength(TypeIIF,noblocks); + SetLength(TypeIIProb,noblocks); + + for block := 0 to noblocks - 1 do + begin + // get index of the abbreviation of term to enter and find corresponding + + // vector(s) to place in the equation + cellstring := IndOrderBox.Items.Strings[block]; + // check for covariates first + if NCovIndep > 0 then + begin + for i := 0 to NCovIndep-1 do + begin + if cellstring = CovariateCode.Items.Strings[i] then // matched! + begin + index := i; // index of covariate code + ColSelected[NEntered] := CovIndepPos[index]; + labelstr := Format('%s', [CovariateCode.Items[index]]); + Labels[NEntered] := labelstr; + NEntered := NEntered + 1; + break; + end; + end; + end; + + // check for fixed effect variables next + if NFixedIndep > 0 then + begin + for i := 0 to NFixedIndep-1 do + begin + if cellstring = FixedIndepCode.Items.Strings[i] then + begin + index := i; + for j := 0 to NFixVecIndep[index]-1 do + begin + ColSelected[NEntered] := FixedIndepPos[index] + j; + labelstr := Format('%s_%d',[FixedIndepCode.Items[index],j+1]); + Labels[NEntered] := labelstr; + NEntered := NEntered + 1; + end; + break; + end; + end; + end; + + // Check for random effects variables next + if NRndIndep > 0 then + begin + for i := 0 to NRndIndep-1 do + begin + if cellstring = RndIndepCode.Items.Strings[i] then + begin + index := i; + for j := 0 to NRndVecIndep[index]-1 do + begin + ColSelected[NEntered] := RndIndepPos[index] + j; + labelstr := Format('%s_%d',[RndIndepCode.Items[index],j+1]); + Labels[NEntered] := labelstr; + NEntered := NEntered + 1; + end; + break; + end; + end; + end; + + // check for interactions next + if NoInterDefs > 0 then + begin + for i := 0 to NoInterDefs-1 do + begin + if cellstring = InteractList.Items.Strings[i] then + begin + for j := 0 to NInteractVecs[i]-1 do + begin + ColSelected[NEntered] := InteractPos[i] + j; + labelstr := Format('%s%d_%d',['IA',i+1,j+1]); + Labels[NEntered] := labelstr; + NEntered := NEntered + 1; + end; + break; + end; + end; + end; // check for interaction variables + + // check for repeated measures variables (person codes) + if NReptDep > 0 then + begin // look for 'IP' in cellstring + labelstr := copy(cellstring,0,2); + if labelstr = 'IP' then // person vectors were generated + begin + for i := 0 to NoCases - 2 do + begin + ColSelected[NEntered] := ReptIndepPos[i]; + Labels[NEntered] := GenLabels[ReptIndepPos[i]]; + NEntered := NEntered + 1; + end; + end; + end; + + // check for repeated treatments + if NReptDep > 0 then + begin // look for 'IR' in cellstring + labelstr := copy(cellstring,0,2); + if labelstr = 'IR' then // repeated treatment vectors were generated + begin + for i := 0 to NReptDep - 2 do + begin + ColSelected[NEntered] := ReptTrtPos[i]; + Labels[NEntered] := GenLabels[ReptTrtPos[i]]; + NEntered := NEntered + 1; + end; + end; + end; + + RegAnal(NEntered, AReport); + R := sqrt(R2); + df1 := Nentered - 1; // no. of independent variables + df2 := totalobs - df1 - 1; // N - no. independent - 1 + SSt := (totalobs-1) * Vars[0]; + SSres := SSt * (1.0 - R2); + VarEst := SSres / df2; + if (VarEst > 0.0) then + StdErrEst := sqrt(VarEst) + else + begin + MessageDlg('Error in computing variance estimate.', mtError, [mbOK], 0); + StdErrEst := 0.0; + end; + if (R2 < 1.0) and (df2 > 0.0) then + F := (R2 / df1) / ((1.0-R2)/ df2) + else + F := 0.0; + FProbF := probf(F,df1,df2); + AdjR2 := 1.0 - (1.0 - R2) * (totalobs - 1) / df2; + + AReport.Add(' R R2 F Prob. > F DF1 DF2 '); + AReport.Add('-------- ---------- ---------- ---------- ----- -----'); + AReport.Add('%8.3f %10.3f %10.3f %10.3f %5.0f %5.0f', [R, R2, F, FProbF, df1, df2]); + AReport.Add(''); + AReport.Add('Adjusted R Squared: %10.3f', [AdjR2]); + AReport.Add('Std. Error of Estimate: %10.3f', [StdErrEst]); + AReport.Add(''); + AReport.Add('Variable Beta B Std.Error t Prob. > t '); + AReport.Add('---------- ---------- ---------- ---------- ---------- ----------'); + df1 := 1.0; + sum := 0.0; + for i := 0 to Nentered - 2 do + begin + SSx := (totalobs-1) * Vars[i+1]; + sum := sum + B[i] * means[i+1]; + if invmatrix[i,i] > 1.0e-15 then + begin + StdErrB := VarEst / (SSx * (1.0 / invmatrix[i,i])); + StdErrB := sqrt(StdErrB); + if StdErrB > 0.0 then F := B[i] / StdErrB else F := 0.0; + FProbF := probf(F*F,df1,df2); + end else + begin + StdErrB := 0.0; + F := 0.0; + FProbF := 0.0; + end; + AReport.Add('%10s %10.3f %10.3f %10.3f %10.3f %10.3f', [Labels[i+1], Beta[i] ,B[i], StdErrB, F, FProbF]); + end; + AReport.Add(''); + constant := means[0] - sum; + AReport.Add('Constant: %10.3f', [constant]); + + // test increment in R2 for this block + R2Increment := R2 - OldR2; + if priorentered > 0 then + df1 := (NEntered-1) - (priorentered-1) + else + df1 := NEntered - 1; + df2 := totalobs - NEntered; + TypeIDF1[block] := df1; + TypeIDF2[block] := df2; + TypeISS[block] := (R2 - OldR2) * SSt; + TypeIMS[block] := TypeISS[block] / df1; + F := ((R2 - OldR2)/ df1) / ((1.0 - R2) / df2); + TypeIF[block] := F; + FProbF := probf(F,df1,df2); + TypeIProb[block] := FProbF; + AReport.Add('Increment in Squared R: %10.3f', [R2Increment]); + AReport.Add('F: %10.3f', [F]); + AReport.Add(' with d.o.f. %10.0f and %.0f',[df1, df2]); // df is double! - why? + AReport.Add(' and Prob > F %10.3f', [FProbF]); + + AReport.Add(''); + AReport.Add('======================================================================================='); + AReport.Add(''); + + OldR2 := R2; + priorentered := NEntered; + // setup for next block analysis + WorkMat := nil; + StdDevs := nil; + Vars := nil; + means := nil; + Beta := nil; + B := nil; + invmatrix := nil; + rxy := nil; + indmatrix := nil; + rmatrix := nil; + end; // next variable block + + // Next, obtain the unique (Type II values) by elimination of each block + // from the full model and testing the decrement in R2 + FullR2 := R2; // save previously obtained full model R2 + for i := 0 to NoBlocks - 1 do + begin NEntered := 0; - OldDF1 := 0.0; - priorentered := 0; - OldR2 := 0; // enter the dependent variable first if NContDep > 0 then begin - ColSelected[0] := ContDepPos[0]; - Labels[0] := GenLabels[1]; + ColSelected[0] := ContDepPos[0]; + Labels[0] := GenLabels[1]; end else begin - ColSelected[0] := ReptDepPos[0]; - Labels[0] := GenLabels[1]; + ColSelected[0] := ReptDepPos[0]; + Labels[0] := GenLabels[1]; end; NEntered := NEntered + 1; - - // Enter independent variables as indicated in indorderbox then interactions - // until the total model is analyzed. Then delete each term to get a - // restricted model and compare to the full model. - noblocks := IndOrderBox.Items.Count; - SetLength(TypeISS,noblocks); - SetLength(TypeIISS,noblocks); - SetLength(TypeIMS,noblocks); - SetLength(TypeIIMS,noblocks); - SetLength(TypeIDF1,noblocks); - SetLength(TypeIDF2,noblocks); - SetLength(TypeIIDF1,noblocks); - SetLength(TypeIIDF2,noblocks); - SetLength(TypeIF,noblocks); - SetLength(TypeIProb,noblocks); - SetLength(TypeIIF,noblocks); - SetLength(TypeIIProb,noblocks); - - for block := 0 to noblocks - 1 do + for block := 0 to NoBlocks - 1 do begin - // get index of the abbreviation of term to enter and find corresponding - // vector(s) to place in the equation + if i = block then + continue // delete this block + else + begin // enter the remaining blocks cellstring := IndOrderBox.Items.Strings[block]; - // check for covariates first + // if a covariate, include it if NCovIndep > 0 then begin - for i := 0 to NCovIndep-1 do + for j := 0 to NCovIndep-1 do + begin + if cellstring = CovariateCode.Items.Strings[j] then // matched! begin - if cellstring = CovariateCode.Items.Strings[i] then // matched! - begin - index := i; // index of covariate code - ColSelected[NEntered] := CovIndepPos[index]; - labelstr := format('%s',[CovariateCode.Items.Strings[index]]); - Labels[NEntered] := labelstr; - NEntered := NEntered + 1; - break; - end; + index := j; // index of covariate code + ColSelected[NEntered] := CovIndepPos[index]; + Labels[NEntered] := Format('%s', [CovariateCode.Items[index]]); + NEntered := NEntered + 1; + break; end; + end; end; // check for fixed effect variables next if NFixedIndep > 0 then begin - for i := 0 to NFixedIndep-1 do + for j := 0 to NFixedIndep-1 do + begin + if cellstring = FixedIndepCode.Items.Strings[j] then begin - if cellstring = FixedIndepCode.Items.Strings[i] then - begin - index := i; - for j := 0 to NFixVecIndep[index]-1 do - begin - ColSelected[NEntered] := FixedIndepPos[index] + j; - labelstr := format('%s_%d',[FixedIndepCode.Items.Strings[index],j+1]); - Labels[NEntered] := labelstr; - NEntered := NEntered + 1; - end; - break; - end; + index := j; + for k := 0 to NFixVecIndep[index]-1 do + begin + ColSelected[NEntered] := FixedIndepPos[index] + k; + Labels[NEntered] := Format('%s_%d', [FixedIndepCode.Items[index], k+1]); + NEntered := NEntered + 1; + end; + break; end; + end; end; // Check for random effects variables next if NRndIndep > 0 then begin - for i := 0 to NRndIndep-1 do + for j := 0 to NRndIndep-1 do + begin + if cellstring = RndIndepCode.Items.Strings[j] then begin - if cellstring = RndIndepCode.Items.Strings[i] then - begin - index := i; - for j := 0 to NRndVecIndep[index]-1 do - begin - ColSelected[NEntered] := RndIndepPos[index] + j; - labelstr := format('%s_%d',[RndIndepCode.Items.Strings[index],j+1]); - Labels[NEntered] := labelstr; - NEntered := NEntered + 1; - end; - break; - end; + index := j; + for k := 0 to NRndVecIndep[index]-1 do + begin + ColSelected[NEntered] := RndIndepPos[index] + k; + Labels[NEntered] := Format('%s_%d',[RndIndepCode.Items[index], k+1]); + NEntered := NEntered + 1; + end; end; + break; + end; end; // check for interactions next if NoInterDefs > 0 then begin - for i := 0 to NoInterDefs-1 do + for j := 0 to NoInterDefs-1 do + begin + if cellstring = InteractList.Items.Strings[j] then begin - if cellstring = InteractList.Items.Strings[i] then - begin - for j := 0 to NInteractVecs[i]-1 do - begin - ColSelected[NEntered] := InteractPos[i] + j; - labelstr := format('%s%d_%d',['IA',i+1,j+1]); - Labels[NEntered] := labelstr; - NEntered := NEntered + 1; - end; - break; - end; - end; - end; // check for interaction variables + for k := 0 to NInteractVecs[j]-1 do + begin + ColSelected[NEntered] := InteractPos[j] + k; + Labels[NEntered] := Format('%s%d_%d', ['IA', j+1, k+1]); + NEntered := NEntered + 1; + end; + break; + end; // end if + end; // next j + end; // end if interdefs > 0 + end; // entry of remaining blocks + end; // enter next block not equal to block i - // check for repeated measures variables (person codes) - if NReptDep > 0 then - begin // look for 'IP' in cellstring - labelstr := copy(cellstring,0,2); - if labelstr = 'IP' then // person vectors were generated - begin - for i := 0 to NoCases - 2 do - begin - ColSelected[NEntered] := ReptIndepPos[i]; - Labels[NEntered] := GenLabels[ReptIndepPos[i]]; - NEntered := NEntered + 1; - end; - end; - end; + RegAnal(NEntered, AReport); // compute restricted model - // check for repeated treatments - if NReptDep > 0 then - begin // look for 'IR' in cellstring - labelstr := copy(cellstring,0,2); - if labelstr = 'IR' then // repeated treatment vectors were generated - begin - for i := 0 to NReptDep - 2 do - begin - ColSelected[NEntered] := ReptTrtPos[i]; - Labels[NEntered] := GenLabels[ReptTrtPos[i]]; - NEntered := NEntered + 1; - end; - end; - end; - - RegAnal(NEntered); - R := sqrt(R2); - df1 := Nentered - 1; // no. of independent variables - df2 := totalobs - df1 - 1; // N - no. independent - 1 - SSt := (totalobs-1) * Vars[0]; - SSres := SSt * (1.0 - R2); - VarEst := SSres / df2; - if (VarEst > 0.0) then StdErrEst := sqrt(VarEst) - else - begin - ShowMessage('ERROR! Error in computing variance estimate.'); - StdErrEst := 0.0; - end; - if (R2 < 1.0) and (df2 > 0.0) then F := (R2 / df1) / ((1.0-R2)/ df2) - else F := 0.0; - FProbF := probf(F,df1,df2); - AdjR2 := 1.0 - (1.0 - R2) * (totalobs - 1) / df2; -// OutputFrm.RichEdit.ParaGraph.Alignment := taLeftJustify; - outline := format('%8s%10s%10s%12s%5s%5s',['R','R2','F','Prob.>F','DF1','DF2']); - OutputFrm.RichEdit.Lines.Add(outline); - outline := format('%8.3f%10.3f%10.3f%10.3f%5.0f%5.0f', - [R,R2,F,FProbF,df1,df2]); - OutputFrm.RichEdit.Lines.Add(outline); - outline := format('Adjusted R Squared = %5.3f',[AdjR2]); - OutputFrm.RichEdit.Lines.Add(outline); - OutputFrm.RichEdit.Lines.Add(''); - outline := format('Std. Error of Estimate = %10.3f',[StdErrEst]); - OutputFrm.RichEdit.Lines.Add(outline); - OutputFrm.RichEdit.Lines.Add(''); - OutputFrm.RichEdit.Lines.Add('Variable Beta B Std.Error t Prob.>t'); - df1 := 1.0; - sum := 0.0; - for i := 0 to Nentered - 2 do - begin - SSx := (totalobs-1) * Vars[i+1]; - sum := sum + B[i] * means[i+1]; - if invmatrix[i,i] > 1.0e-15 then - begin - StdErrB := VarEst / (SSx * (1.0 / invmatrix[i,i])); - StdErrB := sqrt(StdErrB); - if StdErrB > 0.0 then F := B[i] / StdErrB else F := 0.0; - FProbF := probf(F*F,df1,df2); - end - else begin - StdErrB := 0.0; - F := 0.0; - FProbF := 0.0; - end; - cellstring := format('%10s',[Labels[i+1]]); - outline := format('%10s%10.3f%10.3f%10.3f%10.3f%10.3f', - [cellstring, Beta[i] ,B[i], StdErrB, F, FProbF]); - OutputFrm.RichEdit.Lines.Add(outline); - end; - constant := means[0] - sum; - outline := format('Constant = %10.3f',[constant]); - OutputFrm.RichEdit.Lines.Add(outline); - - // test increment in R2 for this block - R2Increment := R2 - OldR2; - if priorentered > 0 then - df1 := (NEntered-1) - (priorentered-1) - else df1 := NEntered - 1; - df2 := totalobs - NEntered; - TypeIDF1[block] := df1; - TypeIDF2[block] := df2; - TypeISS[block] := (R2 - OldR2) * SSt; - TypeIMS[block] := TypeISS[block] / df1; - F := ((R2 - OldR2)/ df1) / ((1.0 - R2) / df2); - TypeIF[block] := F; - FProbF := probf(F,df1,df2); - TypeIProb[block] := FProbF; - outline := format('Increment in Squared R = %10.3f',[R2Increment]); - OutputFrm.RichEdit.Lines.Add(outline); - outline := format('F with degrees freedom %4.0f and %4.0f = %10.3f, Prob.>F = %10.3f', - [df1,df2,F,FProbF]); - OutputFrm.RichEdit.Lines.Add(outline); - OutputFrm.ShowModal; - OldR2 := R2; - priorentered := NEntered; - // setup for next block analysis - WorkMat := nil; - StdDevs := nil; - Vars := nil; - means := nil; - Beta := nil; - B := nil; - invmatrix := nil; - rxy := nil; - indmatrix := nil; - rmatrix := nil; - end; // next variable block - - // Next, obtain the unique (Type II values) by elimination of each block - // from the full model and testing the decrement in R2 - FullR2 := R2; // save previously obtained full model R2 - for i := 0 to NoBlocks - 1 do + if R2 > 0.0 then R := sqrt(R2) else R := 0.0; + df1 := Nentered; // no. of independent variables + df2 := totalobs - df1 - 1; // N - no. independent - 1 + SSt := (totalobs-1) * Vars[0]; + SSres := SSt * (1.0 - R2); + VarEst := SSres / df2; + if (VarEst > 0.0) then + StdErrEst := sqrt(VarEst) + else begin - NEntered := 0; - // enter the dependent variable first - if NContDep > 0 then - begin - ColSelected[0] := ContDepPos[0]; - Labels[0] := GenLabels[1]; - end - else begin - ColSelected[0] := ReptDepPos[0]; - Labels[0] := GenLabels[1]; - end; - NEntered := NEntered + 1; - for block := 0 to NoBlocks - 1 do - begin - if i = block then continue // delete this block - else - begin // enter the remaining blocks - cellstring := IndOrderBox.Items.Strings[block]; - // if a covariate, include it - if NCovIndep > 0 then - begin - for j := 0 to NCovIndep-1 do - begin - if cellstring = CovariateCode.Items.Strings[j] then // matched! - begin - index := j; // index of covariate code - ColSelected[NEntered] := CovIndepPos[index]; - labelstr := format('%s',[CovariateCode.Items.Strings[index]]); - Labels[NEntered] := labelstr; - NEntered := NEntered + 1; - break; - end; - end; - end; - // check for fixed effect variables next - if NFixedIndep > 0 then - begin - for j := 0 to NFixedIndep-1 do - begin - if cellstring = FixedIndepCode.Items.Strings[j] then - begin - index := j; - for k := 0 to NFixVecIndep[index]-1 do - begin - ColSelected[NEntered] := FixedIndepPos[index] + k; - labelstr := format('%s_%d',[FixedIndepCode.Items.Strings[index],k+1]); - Labels[NEntered] := labelstr; - NEntered := NEntered + 1; - end; - break; - end; - end; - end; - // Check for random effects variables next - if NRndIndep > 0 then - begin - for j := 0 to NRndIndep-1 do - begin - if cellstring = RndIndepCode.Items.Strings[j] then - begin - index := j; - for k := 0 to NRndVecIndep[index]-1 do - begin - ColSelected[NEntered] := RndIndepPos[index] + k; - labelstr := format('%s_%d',[RndIndepCode.Items.Strings[index],k+1]); - Labels[NEntered] := labelstr; - NEntered := NEntered + 1; - end; - end; - break; - end; - end; - // check for interactions next - if NoInterDefs > 0 then - begin - for j := 0 to NoInterDefs-1 do - begin - if cellstring = InteractList.Items.Strings[j] then - begin - for k := 0 to NInteractVecs[j]-1 do - begin - ColSelected[NEntered] := InteractPos[j] + k; - labelstr := format('%s%d_%d',['IA',j+1,k+1]); - Labels[NEntered] := labelstr; - NEntered := NEntered + 1; - end; - break; - end; // end if - end; // next j - end; // end if interdefs > 0 - end; // entry of remaining blocks - end; // enter next block not equal to block i + MessageDlg('Error in computing variance estimate.', mtError, [mbOk], 0); + StdErrEst := 0.0; + end; + if (R2 < 1.0) and (df2 > 0.0) then F := (R2 / df1) / ((1.0-R2)/ df2) + else F := 0.0; + FProbF := probf(F,df1,df2); + AdjR2 := 1.0 - (1.0 - R2) * (totalobs - 1) / df2; - RegAnal(NEntered); // compute restricted model - if R2 > 0.0 then R := sqrt(R2) else R := 0.0; - df1 := Nentered; // no. of independent variables - df2 := totalobs - df1 - 1; // N - no. independent - 1 - SSt := (totalobs-1) * Vars[0]; - SSres := SSt * (1.0 - R2); - VarEst := SSres / df2; - if (VarEst > 0.0) then StdErrEst := sqrt(VarEst) - else - begin - ShowMessage('ERROR! Error in computing variance estimate.'); - StdErrEst := 0.0; - end; - if (R2 < 1.0) and (df2 > 0.0) then F := (R2 / df1) / ((1.0-R2)/ df2) - else F := 0.0; - FProbF := probf(F,df1,df2); - AdjR2 := 1.0 - (1.0 - R2) * (totalobs - 1) / df2; -// OutputFrm.RichEdit.ParaGraph.Alignment := taLeftJustify; - outline := format('%8s%10s%10s%12s%5s%5s',['R','R2','F','Prob.>F','DF1','DF2']); - OutputFrm.RichEdit.Lines.Add(outline); - outline := format('%8.3f%10.3f%10.3f%10.3f%5.0f%5.0f', - [R,R2,F,FProbF,df1,df2]); - OutputFrm.RichEdit.Lines.Add(outline); - outline := format('Adjusted R Squared = %5.3f',[AdjR2]); - OutputFrm.RichEdit.Lines.Add(outline); - OutputFrm.RichEdit.Lines.Add(''); - outline := format('Std. Error of Estimate = %10.3f',[StdErrEst]); - OutputFrm.RichEdit.Lines.Add(outline); - OutputFrm.RichEdit.Lines.Add(''); - OutputFrm.RichEdit.Lines.Add('Variable Beta B Std.Error t Prob.>t'); - df1 := 1.0; - sum := 0.0; - for j := 0 to Nentered - 2 do - begin - SSx := (totalobs-1) * Vars[j+1]; - sum := sum + B[j] * means[j+1]; - if invmatrix[j,j] > 1.0e-18 then - StdErrB := VarEst / (SSx * (1.0 / invmatrix[j,j])) - else StdErrB := 0.0; - if StdErrB > 0.0 then StdErrB := sqrt(StdErrB); - if StdErrB > 0.0 then F := B[j] / StdErrB else F := 0.0; - FProbF := probf(F*F,df1,df2); - cellstring := format('%10s',[Labels[j+1]]); - outline := format('%10s%10.3f%10.3f%10.3f%10.3f%10.3f', - [cellstring, Beta[j] ,B[j], StdErrB, F, FProbF]); - OutputFrm.RichEdit.Lines.Add(outline); - end; - constant := means[0] - sum; - outline := format('Constant = %10.3f',[constant]); - OutputFrm.RichEdit.Lines.Add(outline); + AReport.Add(' R R2 F Prob. > F DF1 DF2 '); + AReport.Add('-------- ---------- ---------- ---------- ----- -----'); + AReport.Add('%8.3f %10.3f %10.3f %10.3f %5.0f %5.0f', [R, R2, F, FProbF, df1, df2]); + AReport.Add(''); + AReport.Add('Adjusted R Squared: %10.3f', [AdjR2]); + AReport.Add('Std. Error of Estimate: %10.3f', [StdErrEst]); + AReport.Add(''); + AReport.Add('Variable Beta B Std.Error t Prob. > t '); + AReport.Add('---------- ---------- ---------- ---------- ---------- ----------'); - // Now compute unique contribution of block left out (Type II) - R2Increment := FullR2 - R2; - df1 := (novars - 2) - (NEntered - 1); // k1 - k2 - df2 := totalobs - (novars - 2) - 1; - TypeIIDF1[i] := df1; - TypeIIDF2[i] := df2; - TypeIISS[i] := (FullR2 - R2) * SSt; - TypeIIMS[i] := TypeIISS[i] / df1; - F := ((FullR2 - R2)/ df1) / ((1.0 - FullR2) / df2); - TypeIIF[i] := F; - FProbF := probf(F,df1,df2); - TypeIIProb[i] := FProbF; - outline := format('Decrement in Squared R = %10.3f',[R2Increment]); - OutputFrm.RichEdit.Lines.Add(outline); - outline := format('F with degrees freedom %4.0f and %4.0f = %10.3f, Prob.>F = %10.3f', - [df1,df2,F,FProbF]); - OutputFrm.RichEdit.Lines.Add(outline); - OutputFrm.ShowModal; - // setup for next block analysis - WorkMat := nil; - StdDevs := nil; - Vars := nil; - means := nil; - Beta := nil; - B := nil; - invmatrix := nil; - rxy := nil; - indmatrix := nil; - rmatrix := nil; - end; // next i block selected for elimination - - // Show summary table of Type I and Type II tests - OutputFrm.RichEdit.Clear; - OutputFrm.RichEdit.Lines.Add('Summary Table for GLM Effects'); - OutputFrm.RichEdit.Lines.Add(''); - OutputFrm.RichEdit.Lines.Add('Incremental Effects.'); - OutputFrm.RichEdit.Lines.Add('SOURCE DF1 DF2 SS MS F PROB>F'); - for i := 0 to NoBlocks - 1 do + df1 := 1.0; + sum := 0.0; + for j := 0 to Nentered - 2 do begin + SSx := (totalobs-1) * Vars[j+1]; + sum := sum + B[j] * means[j+1]; + if invmatrix[j,j] > 1.0e-18 then + StdErrB := VarEst / (SSx * (1.0 / invmatrix[j,j])) + else StdErrB := 0.0; + if StdErrB > 0.0 then StdErrB := sqrt(StdErrB); + if StdErrB > 0.0 then F := B[j] / StdErrB else F := 0.0; + FProbF := probf(F*F,df1,df2); + AReport.Add('%10s %10.3f %10.3f %10.3f %10.3f %10.3f', [Labels[j+1], Beta[j] ,B[j], StdErrB, F, FProbF]); + end; + AReport.Add(''); + constant := means[0] - sum; + AReport.Add('Constant: %10.3f', [constant]); + + // Now compute unique contribution of block left out (Type II) + R2Increment := FullR2 - R2; + df1 := (novars - 2) - (NEntered - 1); // k1 - k2 + df2 := totalobs - (novars - 2) - 1; + TypeIIDF1[i] := df1; + TypeIIDF2[i] := df2; + TypeIISS[i] := (FullR2 - R2) * SSt; + TypeIIMS[i] := TypeIISS[i] / df1; + F := ((FullR2 - R2)/ df1) / ((1.0 - FullR2) / df2); + TypeIIF[i] := F; + FProbF := probf(F,df1,df2); + TypeIIProb[i] := FProbF; + + AReport.Add('Decrement in Squared R: %10.3f', [R2Increment]); + AReport.Add('F: %10.3f', [F]); + AReport.Add(' with d.o.f. %10.0f and %.0f',[df1, df2]); + AReport.Add(' and Prob > F %10.3f', [FProbF]); + + AReport.Add(''); + AReport.Add('======================================================================================='); + AReport.Add(''); + + // setup for next block analysis + WorkMat := nil; + StdDevs := nil; + Vars := nil; + means := nil; + Beta := nil; + B := nil; + invmatrix := nil; + rxy := nil; + indmatrix := nil; + rmatrix := nil; + end; // next i block selected for elimination + + // Show summary table of Type I and Type II tests + AReport.Add('SUMMARY TABLE FOR GLM EFFECTS'); + AReport.Add(''); + AReport.Add('Incremental Effects:'); + AReport.Add('SOURCE DF1 DF2 SS MS F Prob > F'); + AReport.Add('---------- ---- ---- ---------- ---------- ---------- --------'); + for i := 0 to NoBlocks - 1 do + begin + cellstring := IndOrderBox.Items.Strings[i]; + AReport.Add('%10s %4.0f %4.0f %10.3f %10.3f %10.3f %8.3f', + [cellstring,TypeIDF1[i],TypeIDF2[i],TypeISS[i],TypeIMS[i],TypeIF[i],TypeIProb[i]] + ); + end; + AReport.Add(''); + AReport.Add('Unique Effects:'); + AReport.Add('SOURCE DF1 DF2 SS MS F Prob > F'); + AReport.Add('---------- ---- ---- ---------- ---------- ---------- --------'); + for i := 0 to NoBlocks - 1 do + begin + cellstring := IndOrderBox.Items.Strings[i]; + AReport.Add('%10s %4.0f %4.0f %10.3f %10.3f %10.3f %8.3f', + [cellstring,TypeIIDF1[i],TypeIIDF2[i],TypeIISS[i],TypeIIMS[i],TypeIIF[i],TypeIIProb[i]] + ); + end; + + AReport.Add(''); + AReport.Add('======================================================================================='); + AReport.Add(''); + + // Show Anova Results for fixed and/or covariates + if (NRndIndep = 0) and (NReptDep = 0) then // must be fixed and/or covariate only design + begin + if (NFixedIndep > 0) or (NCovIndep > 0) then // fixed effects + begin + df1 := novars - 2; // k1 (note: novars contains ID variable, dep, independents) + PredSS := SSt * FullR2; + PredMS := PredSS / df1; + df2 := totalobs - df1 - 1; // residual df + SSres := SSt * (1.0 - FullR2); + VarEst := SSres / df2; // ms residual + F := PredMS / VarEst; + FProbF := probf(F,df1,df2); + AReport.Add('SOURCE DF SS MS F Prob > F'); + AReport.Add('-------------------- ---- ---------- ---------- ---------- --------'); + AReport.Add('%20s %4.0f %10.3f %10.3f %10.3f %8.3f', ['Full Model', df1, PredSS, PredMS, F, FProbF]); + for i := 0 to NoBlocks - 1 do + begin + F := TypeIMS[i] / VarEst; + FProbF := probf(F,TypeIDF1[i],df2); cellstring := IndOrderBox.Items.Strings[i]; - outline := format('%10s %3.0f %3.0f %10.3f %10.3f %10.3f %6.3f', - [cellstring,TypeIDF1[i],TypeIDF2[i],TypeISS[i],TypeIMS[i],TypeIF[i],TypeIProb[i]]); - OutputFrm.RichEdit.Lines.Add(outline); + AReport.Add('%20s %4.0f %10.3f %10.3f %10.3f %8.3f', [cellstring, TypeIDF1[i], TypeISS[i], TypeIMS[i], F, FProbF]); + end; + AReport.Add('%20s %4.0f %10.3f %10.3f', ['Residual', df2, SSres, VarEst]); + AReport.Add('%20s %4d %10.3f', ['Total', totalobs-1, SSt]); + AReport.Add(''); + AReport.Add('======================================================================================='); + AReport.Add(''); end; - OutputFrm.RichEdit.Lines.Add(''); - OutputFrm.RichEdit.Lines.Add('Unique Effects.'); - OutputFrm.RichEdit.Lines.Add('SOURCE DF1 DF2 SS MS F PROB>F'); + end; + + // Show Anova Results for random effects and/or covariates + if (NFixedIndep = 0) and (NReptDep = 0) then // must be random only or covariate only design + begin + if (NRndIndep > 0) or (NCovIndep > 0) then // random and/or covariate effects + begin + df1 := novars - 2; // k1 (note: novars contains ID variable, dep, independents) + PredSS := SSt * FullR2; + PredMS := PredSS / df1; + df2 := totalobs - df1 - 1; // residual df + SSres := SSt * (1.0 - FullR2); + VarEst := SSres / df2; // ms residual + F := PredMS / VarEst; + FProbF := probf(F,df1,df2); + AReport.Add('SOURCE DF SS MS F Prob > F'); + AReport.Add('-------------------- ---- ---------- ---------- ---------- --------'); + AReport.Add('%20s %4.0f %10.3f %10.3f %10.3f %8.3f', ['Full Model', df1, PredSS, PredMS, F, FProbF]); + for i := 0 to NoBlocks - 1 do + begin + F := TypeIMS[i] / VarEst; + FProbF := probf(F,TypeIDF1[i],df2); + AReport.Add('%20s %4.0f %10.3f %10.3f %10.3f %8.3f', [Labels[i+1], TypeIDF1[i], TypeISS[i], TypeIMS[i], F, FProbF]); + end; + AReport.Add('%20s %4.0f %10.3f %10.3f', ['Residual', df2, SSres, VarEst]); + AReport.Add('%20s %4d %10.3f', ['Total', totalobs-1, SSt]); + AReport.Add(''); + AReport.Add('======================================================================================='); + AReport.Add(''); + end; + end; + + // show effects for repeated measures ANOVA (and covariates) + if NReptDep > 0 then + begin + df1 := novars - 2; // k1 (note: novars contains ID variable, dep, independents) + PredSS := SSt * FullR2; + PredMS := PredSS / df1; + df2 := totalobs - df1 - 1; // residual df + SSres := SSt * (1.0 - FullR2); + VarEst := SSres / df2; // ms residual + F := PredMS / VarEst; + FProbF := probf(F,df1,df2); + AReport.Add('SOURCE DF SS MS F Prob > F'); + AReport.Add('-------------------- ---- ---------- ---------- ---------- --------'); + AReport.Add('%20s %4.0f %10.3f %10.3f %10.3f %8.3f', ['Full Model', df1, PredSS, PredMS, F, FProbF]); for i := 0 to NoBlocks - 1 do begin - cellstring := IndOrderBox.Items.Strings[i]; - outline := format('%10s %3.0f %3.0f %10.3f %10.3f %10.3f %6.3f', - [cellstring,TypeIIDF1[i],TypeIIDF2[i],TypeIISS[i],TypeIIMS[i],TypeIIF[i],TypeIIProb[i]]); - OutputFrm.RichEdit.Lines.Add(outline); + F := TypeIMS[i] / VarEst; + FProbF := probf(F,TypeIDF1[i],df2); + AReport.Add('%20s %4.0f %10.3f %10.3f %10.3f %8.3f', [Labels[i+1], TypeIDF1[i], TypeISS[i], TypeIMS[i], F, FProbF]); end; - OutputFrm.ShowModal; + AReport.Add('%20s %4.0f %10.3f %10.3f', ['Residual', df2, SSres, VarEst]); + AReport.Add('%20s %4d %10.3f', ['Total', totalobs-1, SSt]); + AReport.Add(''); + AReport.Add('======================================================================================='); + AReport.Add(''); + end; - // Show Anova Results for fixed and/or covariates - OutputFrm.RichEdit.Clear; - if (NRndIndep = 0) and (NReptDep = 0) then // must be fixed and/or covariate only design - begin - if (NFixedIndep > 0) or (NCovIndep > 0) then // fixed effects - begin - df1 := novars - 2; // k1 (note: novars contains ID variable, dep, independents) - PredSS := SSt * FullR2; - PredMS := PredSS / df1; - df2 := totalobs - df1 - 1; // residual df - SSres := SSt * (1.0 - FullR2); - VarEst := SSres / df2; // ms residual - F := PredMS / VarEst; - FProbF := probf(F,df1,df2); - OutputFrm.RichEdit.Lines.Add('SOURCE DF SS MS F PROB>F'); - outline := format('%20s %3.0f %10.3f %10.3f %10.3f %6.3f', - ['Full Model',df1,PredSS,PredMS,F,FProbF]); - OutputFrm.RichEdit.Lines.Add(outline); - for i := 0 to NoBlocks - 1 do - begin - F := TypeIMS[i] / VarEst; - FProbF := probf(F,TypeIDF1[i],df2); - cellstring := IndOrderBox.Items.Strings[i]; - outline := format('%20s %3.0f %10.3f %10.3f %10.3f %6.3f', - [cellstring,TypeIDF1[i],TypeISS[i],TypeIMS[i],F,FProbF]); - OutputFrm.RichEdit.Lines.Add(outline); - end; - outline := format('%20s %3.0f %10.3f %10.3f', - ['Residual',df2,SSres,VarEst]); - OutputFrm.RichEdit.Lines.Add(outline); - outline := format('%20s %3d %10.3f', - ['Total',totalobs-1,SSt]); - OutputFrm.RichEdit.Lines.Add(outline); - OutputFrm.ShowModal; - end; - end; - - // Show Anova Results for random effects and/or covariates - OutputFrm.RichEdit.Clear; - if (NFixedIndep = 0) and (NReptDep = 0) then // must be random only or covariate only design - begin - if (NRndIndep > 0) or (NCovIndep > 0) then // random and/or covariate effects - begin - df1 := novars - 2; // k1 (note: novars contains ID variable, dep, independents) - PredSS := SSt * FullR2; - PredMS := PredSS / df1; - df2 := totalobs - df1 - 1; // residual df - SSres := SSt * (1.0 - FullR2); - VarEst := SSres / df2; // ms residual - F := PredMS / VarEst; - FProbF := probf(F,df1,df2); - OutputFrm.RichEdit.Lines.Add('SOURCE DF SS MS F PROB>F'); - outline := format('%20s %3.0f %10.3f %10.3f %10.3f %6.3f', - ['Full Model',df1,PredSS,PredMS,F,FProbF]); - OutputFrm.RichEdit.Lines.Add(outline); - for i := 0 to NoBlocks - 1 do - begin - F := TypeIMS[i] / VarEst; - FProbF := probf(F,TypeIDF1[i],df2); - outline := format('%20s %3.0f %10.3f %10.3f %10.3f %6.3f', - [Labels[i+1],TypeIDF1[i],TypeISS[i],TypeIMS[i],F,FProbF]); - OutputFrm.RichEdit.Lines.Add(outline); - end; - outline := format('%20s %3.0f %10.3f %10.3f', - ['Residual',df2,SSres,VarEst]); - OutputFrm.RichEdit.Lines.Add(outline); - outline := format('%20s %3d %10.3f', - ['Total',totalobs-1,SSt]); - OutputFrm.RichEdit.Lines.Add(outline); - OutputFrm.ShowModal; - end; - end; - - // show effects for repeated measures ANOVA (and covariates) - OutputFrm.RichEdit.Clear; - if NReptDep > 0 then - begin - df1 := novars - 2; // k1 (note: novars contains ID variable, dep, independents) - PredSS := SSt * FullR2; - PredMS := PredSS / df1; - df2 := totalobs - df1 - 1; // residual df - SSres := SSt * (1.0 - FullR2); - VarEst := SSres / df2; // ms residual - F := PredMS / VarEst; - FProbF := probf(F,df1,df2); - OutputFrm.RichEdit.Lines.Add('SOURCE DF SS MS F PROB>F'); - outline := format('%20s %3.0f %10.3f %10.3f %10.3f %6.3f', - ['Full Model',df1,PredSS,PredMS,F,FProbF]); - OutputFrm.RichEdit.Lines.Add(outline); - for i := 0 to NoBlocks - 1 do - begin - F := TypeIMS[i] / VarEst; - FProbF := probf(F,TypeIDF1[i],df2); - outline := format('%20s %3.0f %10.3f %10.3f %10.3f %6.3f', - [Labels[i+1],TypeIDF1[i],TypeISS[i],TypeIMS[i],F,FProbF]); - OutputFrm.RichEdit.Lines.Add(outline); - end; - outline := format('%20s %3.0f %10.3f %10.3f', - ['Residual',df2,SSres,VarEst]); - OutputFrm.RichEdit.Lines.Add(outline); - outline := format('%20s %3d %10.3f', - ['Total',totalobs-1,SSt]); - OutputFrm.RichEdit.Lines.Add(outline); - OutputFrm.ShowModal; - end; - - // clean up the heap - TypeIIProb := nil; - TypeIIF := nil; - TypeIProb := nil; - TypeIF := nil; - TypeIIDF2 := nil; - TypeIIDF1 := nil; - TypeIDF2 := nil; - TypeIDF1 := nil; - TypeIIMS := nil; - TypeIMS := nil; - TypeIISS := nil; - TypeISS := nil; + // clean up the heap + TypeIIProb := nil; + TypeIIF := nil; + TypeIProb := nil; + TypeIF := nil; + TypeIIDF2 := nil; + TypeIIDF1 := nil; + TypeIDF2 := nil; + TypeIDF1 := nil; + TypeIIMS := nil; + TypeIMS := nil; + TypeIISS := nil; + TypeISS := nil; end; procedure TGLMFrm.ModelIIAnalysis; @@ -2196,428 +2270,426 @@ begin TypeISS := nil; end; -procedure TGLMFrm.ModelIIIAnalysis; +procedure TGLMFrm.ModelIIIAnalysis(AReport: TStrings); var - block, i, j, NEntered, index, noblocks, priorentered : integer; - cellstring : string; - labelstr : string; - outline, effstr : string; - R, SSx, sum, constant: double; - df1, df2, F, FProbF, StdErrB, OldDF1: double; - SSt, VarEst, SSres, StdErrEst, AdjR2 : double; - dfbetween, dferrbetween, dfwithin, dferrwithin : double; - ssbetween, sserrbetween, mserrbetween, sswithin, sserrwithin, mserrwithin : double; - betweenblock : integer; - totalss, totaldf : double; - + block, i, j, NEntered, index, noblocks, priorentered : integer; + cellstring : string; + labelstr : string; + outline, effstr : string; + R, SSx, sum, constant: double; + df1, df2, F, FProbF, StdErrB, OldDF1: double; + SSt, VarEst, SSres, StdErrEst, AdjR2 : double; + dfbetween, dferrbetween, dfwithin, dferrwithin : double; + ssbetween, sserrbetween, mserrbetween, sswithin, sserrwithin, mserrwithin : double; + betweenblock : integer; + totalss, totaldf : double; begin - OldDF1 := 0.0; - priorentered := 0; - OldR2 := 0; + OldDF1 := 0.0; + priorentered := 0; + OldR2 := 0; + ColSelected[0] := ReptDepPos[0]; + Labels[0] := GenLabels[1]; + // Complete an individual regression analysis for each between subjects var. + // Enter each block containing between subjects variance including: + // (1) covariates + // (2) person vectors + // (3) fixed or random factors + // (4) the interactions among only fixed or random effects + noblocks := IndOrderBox.Items.Count; + SetLength(TypeISS,noblocks); // use for between subject effects + SetLength(TypeIISS,noblocks);// use for within subject effects + SetLength(TypeIMS,noblocks); + SetLength(TypeIIMS,noblocks); + SetLength(TypeIDF1,noblocks); + SetLength(TypeIDF2,noblocks); + SetLength(TypeIIDF1,noblocks); + SetLength(TypeIIDF2,noblocks); + SetLength(TypeIF,noblocks); + SetLength(TypeIProb,noblocks); + SetLength(TypeIIF,noblocks); + SetLength(TypeIIProb,noblocks); + + for i := 0 to noblocks - 1 do + begin + TypeISS[i] := -1.0; // store indicator for block (-1 indicates no use) + TypeIISS[i] := -1.0; + end; + + for block := 0 to noblocks - 1 do + begin ColSelected[0] := ReptDepPos[0]; Labels[0] := GenLabels[1]; - // Complete an individual regression analysis for each between subjects var. - // Enter each block containing between subjects variance including: - // (1) covariates - // (2) person vectors - // (3) fixed or random factors - // (4) the interactions among only fixed or random effects - noblocks := IndOrderBox.Items.Count; - SetLength(TypeISS,noblocks); // use for between subject effects - SetLength(TypeIISS,noblocks);// use for within subject effects - SetLength(TypeIMS,noblocks); - SetLength(TypeIIMS,noblocks); - SetLength(TypeIDF1,noblocks); - SetLength(TypeIDF2,noblocks); - SetLength(TypeIIDF1,noblocks); - SetLength(TypeIIDF2,noblocks); - SetLength(TypeIF,noblocks); - SetLength(TypeIProb,noblocks); - SetLength(TypeIIF,noblocks); - SetLength(TypeIIProb,noblocks); + NEntered := 1; + cellstring := IndOrderBox.Items.Strings[block]; + effstr := cellstring; + j := Pos('IR',cellstring); + if j <> 0 then continue; - for i := 0 to noblocks - 1 do - begin - TypeISS[i] := -1.0; // store indicator for block (-1 indicates no use) - TypeIISS[i] := -1.0; + // check for repeated measures variables (person codes) + if NReptDep > 0 then + begin // look for 'IP' in cellstring + labelstr := copy(cellstring,0,2); + if labelstr = 'IP' then // person vectors were generated + begin + betweenblock := block; // save block no. of between subject vectors + for i := 0 to NoCases - 2 do + begin + ColSelected[NEntered] := ReptIndepPos[i]; + Labels[NEntered] := GenLabels[ReptIndepPos[i]]; + NEntered := NEntered + 1; + end; + end; end; - for block := 0 to noblocks - 1 do + // check for fixed effect variables next + if NFixedIndep > 0 then begin - ColSelected[0] := ReptDepPos[0]; - Labels[0] := GenLabels[1]; - NEntered := 1; - cellstring := IndOrderBox.Items.Strings[block]; - effstr := cellstring; - j := Pos('IR',cellstring); - if j <> 0 then continue; - // check for repeated measures variables (person codes) - if NReptDep > 0 then - begin // look for 'IP' in cellstring - labelstr := copy(cellstring,0,2); - if labelstr = 'IP' then // person vectors were generated - begin - betweenblock := block; // save block no. of between subject vectors - for i := 0 to NoCases - 2 do - begin - ColSelected[NEntered] := ReptIndepPos[i]; - Labels[NEntered] := GenLabels[ReptIndepPos[i]]; - NEntered := NEntered + 1; - end; - end; - end; - // check for fixed effect variables next - if NFixedIndep > 0 then + for i := 0 to NFixedIndep-1 do + begin + if cellstring = FixedIndepCode.Items.Strings[i] then begin - for i := 0 to NFixedIndep-1 do - begin - if cellstring = FixedIndepCode.Items.Strings[i] then - begin - index := i; - for j := 0 to NFixVecIndep[index]-1 do - begin - ColSelected[NEntered] := FixedIndepPos[index] + j; - labelstr := format('%s_%d',[FixedIndepCode.Items.Strings[index],j+1]); - Labels[NEntered] := labelstr; - NEntered := NEntered + 1; - end; - break; - end; - end; + index := i; + for j := 0 to NFixVecIndep[index]-1 do + begin + ColSelected[NEntered] := FixedIndepPos[index] + j; + labelstr := format('%s_%d',[FixedIndepCode.Items.Strings[index],j+1]); + Labels[NEntered] := labelstr; + NEntered := NEntered + 1; + end; + break; end; - // Check for random effects variables next - if NRndIndep > 0 then - begin - for i := 0 to NRndIndep-1 do - begin - if cellstring = RndIndepCode.Items.Strings[i] then - begin - index := i; - for j := 0 to NRndVecIndep[index]-1 do - begin - ColSelected[NEntered] := RndIndepPos[index] + j; - labelstr := format('%s_%d',[RndIndepCode.Items.Strings[index],j+1]); - Labels[NEntered] := labelstr; - NEntered := NEntered + 1; - end; - break; - end; - end; - end; - // check for interactions next - if NoInterDefs > 0 then - begin - for i := 0 to NoInterDefs-1 do - begin - if cellstring = InteractList.Items.Strings[i] then - begin - // eliminate any interactions containing 'IR' - j := Pos('IR',cellstring); - if j <> 0 then continue; - for j := 0 to NInteractVecs[i]-1 do - begin - ColSelected[NEntered] := InteractPos[i] + j; - labelstr := format('%s%d_%d',['IA',i+1,j+1]); - Labels[NEntered] := labelstr; - NEntered := NEntered + 1; - end; - break; - end; - end; - end; // check for interaction variables - // check for covariates - if NCovIndep > 0 then - begin - for i := 0 to NCovIndep-1 do - begin - if cellstring = CovariateCode.Items.Strings[i] then // matched! - begin - index := i; // index of covariate code - ColSelected[NEntered] := CovIndepPos[index]; - labelstr := format('%s',[CovariateCode.Items.Strings[index]]); - Labels[NEntered] := labelstr; - NEntered := NEntered + 1; - break; - end; - end; - end; - - // do reg analysis and save sum of squares - RegAnal(NEntered); - R := sqrt(R2); - df1 := Nentered - 1; // no. of independent variables - TypeIDF1[block] := df1; - df2 := totalobs - df1 - 1; // N - no. independent - 1 - SSt := (totalobs-1) * Vars[0]; - SSres := SSt * (1.0 - R2); - VarEst := SSres / df2; - if (VarEst > 0.0) then StdErrEst := sqrt(VarEst) - else - begin - ShowMessage('ERROR! Error in computing variance estimate.'); - StdErrEst := 0.0; - end; - if (R2 < 1.0) and (df2 > 0.0) then F := (R2 / df1) / ((1.0-R2)/ df2) - else F := 0.0; - FProbF := probf(F,df1,df2); - AdjR2 := 1.0 - (1.0 - R2) * (totalobs - 1) / df2; -// OutputFrm.RichEdit.ParaGraph.Alignment := taLeftJustify; - outline := format('%8s%10s%10s%12s%5s%5s',['R','R2','F','Prob.>F','DF1','DF2']); - OutputFrm.RichEdit.Lines.Add(outline); - outline := format('%8.3f%10.3f%10.3f%10.3f%5.0f%5.0f', - [R,R2,F,FProbF,df1,df2]); - OutputFrm.RichEdit.Lines.Add(outline); - outline := format('Adjusted R Squared = %5.3f',[AdjR2]); - OutputFrm.RichEdit.Lines.Add(outline); - OutputFrm.RichEdit.Lines.Add(''); - outline := format('Std. Error of Estimate = %10.3f',[StdErrEst]); - OutputFrm.RichEdit.Lines.Add(outline); - OutputFrm.RichEdit.Lines.Add(''); - OutputFrm.RichEdit.Lines.Add('Variable Beta B Std.Error t Prob.>t'); - df1 := 1.0; - sum := 0.0; - for i := 0 to Nentered - 2 do - begin - SSx := (totalobs-1) * Vars[i+1]; - sum := sum + B[i] * means[i+1]; - if invmatrix[i,i] > 1.0e-15 then - begin - StdErrB := VarEst / (SSx * (1.0 / invmatrix[i,i])); - StdErrB := sqrt(StdErrB); - if StdErrB > 0.0 then F := B[i] / StdErrB else F := 0.0; - FProbF := probf(F*F,df1,df2); - end - else begin - StdErrB := 0.0; - F := 0.0; - FProbF := 0.0; - end; - cellstring := format('%10s',[Labels[i+1]]); - outline := format('%10s%10.3f%10.3f%10.3f%10.3f%10.3f', - [cellstring, Beta[i] ,B[i], StdErrB, F, FProbF]); - OutputFrm.RichEdit.Lines.Add(outline); - end; - constant := means[0] - sum; - outline := format('Constant = %10.3f',[constant]); - OutputFrm.RichEdit.Lines.Add(outline); - TypeISS[block] := R2 * SST; - OutputFrm.RichEdit.Lines.Add('BETWEEN SUBJECT EFFECT:'); - outline := format('SS for %-10s = %10.3f',[effstr,TypeISS[block]]); - OutputFrm.RichEdit.Lines.Add(outline); - outline := format('SS TOTAL = %10.3f',[SST]); - OutputFrm.RichEdit.Lines.Add(outline); - OutputFrm.ShowModal; + end; end; - // Summarize between subject effects - totalss := 0.0; - totaldf := 0.0; - for i := 0 to noblocks - 1 do + // Check for random effects variables next + if NRndIndep > 0 then begin - if TypeISS[i] < 0.0 then continue; - if betweenblock = i then + for i := 0 to NRndIndep-1 do + begin + if cellstring = RndIndepCode.Items.Strings[i] then begin - ssbetween := TypeISS[i]; - dfbetween := TypeIDF1[i]; - end - else - begin - totalss := totalss + TypeISS[i]; - totaldf := totaldf + TypeIDF1[i]; + index := i; + for j := 0 to NRndVecIndep[index]-1 do + begin + ColSelected[NEntered] := RndIndepPos[index] + j; + labelstr := format('%s_%d',[RndIndepCode.Items.Strings[index],j+1]); + Labels[NEntered] := labelstr; + NEntered := NEntered + 1; + end; + break; end; + end; end; - sserrbetween := ssbetween - totalss; - dferrbetween := dfbetween - totaldf; - mserrbetween := sserrbetween / dferrbetween; - OutputFrm.RichEdit.Lines.Clear; - OutputFrm.RichEdit.Lines.Add(' SUMMARY OF BETWEEN SUBJECT EFFECTS'); - outline := 'SOURCE DF SS MS F PROB.>F'; - OutputFrm.RichEdit.Lines.Add(outline); - OutputFrm.RichEdit.Lines.Add(''); - outline := format('%-19s %3.0f %9.3f',['Between Subjects',dfbetween, ssbetween]); - OutputFrm.RichEdit.Lines.Add(outline); - for i := 0 to noblocks - 1 do + // check for interactions next + if NoInterDefs > 0 then begin - if TypeISS[i] < 0.0 then continue; - if betweenblock = i then continue; // already done above - TypeIMS[i] := TypeISS[i] / TypeIDF1[i]; - TypeIF[i] := TypeIMS[i] / mserrbetween; - TypeIDF2[i] := dferrbetween; - TypeIProb[i] := probf(TypeIF[i],TypeIDF1[i],TypeIDF2[i]); - outline := format('%19s %3.0f %9.3f %9.3f %9.3f %9.3f', - [IndOrderBox.Items.Strings[i],TypeIDF1[i],TypeISS[i],TypeIMS[i], - TypeIF[i],TypeIProb[i]]); - OutputFrm.RichEdit.Lines.Add(outline); - end; - outline := format('%19s %3.0f %9.3f %9.3f',['Error Between', dferrbetween, - sserrbetween, mserrbetween]); - OutputFrm.RichEdit.Lines.Add(outline); - OutputFrm.ShowModal; - - // Now, get within subject effects - sswithin := SST - SSbetween; - dfwithin := totalobs - dfbetween - 1; - for block := 0 to noblocks - 1 do - begin - ColSelected[0] := ReptDepPos[0]; - Labels[0] := GenLabels[1]; - NEntered := 1; - cellstring := IndOrderBox.Items.Strings[block]; - effstr := cellstring; - j := Pos('IR',cellstring); - if j = 0 then continue; // only select those for rep. treatments or interactions - - // check for treatments - if NReptDep > 0 then - begin // look for 'IR' in cellstring - labelstr := copy(cellstring,0,2); - if labelstr = 'IR' then // repeated treatment vectors were generated - begin - for i := 0 to NReptDep - 2 do - begin - ColSelected[NEntered] := ReptTrtPos[i]; - Labels[NEntered] := GenLabels[ReptTrtPos[i]]; - NEntered := NEntered + 1; - end; - end; - end; - // check for interactions next - if NoInterDefs > 0 then + for i := 0 to NoInterDefs-1 do + begin + if cellstring = InteractList.Items.Strings[i] then begin - for i := 0 to NoInterDefs-1 do - begin - if cellstring = InteractList.Items.Strings[i] then - begin - for j := 0 to NInteractVecs[i]-1 do - begin - ColSelected[NEntered] := InteractPos[i] + j; - labelstr := format('%s%d_%d',['IA',i+1,j+1]); - Labels[NEntered] := labelstr; - NEntered := NEntered + 1; - end; - break; - end; - end; - end; // check for interaction variables - // do reg analysis and save sum of squares - if NEntered < 2 then continue; - RegAnal(NEntered); - R := sqrt(R2); - df1 := Nentered - 1; // no. of independent variables - TypeIIDF1[block] := df1; - df2 := totalobs - df1 - 1; // N - no. independent - 1 - SSt := (totalobs-1) * Vars[0]; - SSres := SSt * (1.0 - R2); - VarEst := SSres / df2; - if (VarEst > 0.0) then StdErrEst := sqrt(VarEst) - else - begin - ShowMessage('ERROR! Error in computing variance estimate.'); - StdErrEst := 0.0; + // eliminate any interactions containing 'IR' + j := Pos('IR',cellstring); + if j <> 0 then continue; + for j := 0 to NInteractVecs[i]-1 do + begin + ColSelected[NEntered] := InteractPos[i] + j; + labelstr := format('%s%d_%d',['IA',i+1,j+1]); + Labels[NEntered] := labelstr; + NEntered := NEntered + 1; + end; + break; end; - if (R2 < 1.0) and (df2 > 0.0) then F := (R2 / df1) / ((1.0-R2)/ df2) - else F := 0.0; - FProbF := probf(F,df1,df2); - AdjR2 := 1.0 - (1.0 - R2) * (totalobs - 1) / df2; -// OutputFrm.RichEdit.ParaGraph.Alignment := taLeftJustify; - outline := format('%8s%10s%10s%12s%5s%5s',['R','R2','F','Prob.>F','DF1','DF2']); - OutputFrm.RichEdit.Lines.Add(outline); - outline := format('%8.3f%10.3f%10.3f%10.3f%5.0f%5.0f', - [R,R2,F,FProbF,df1,df2]); - OutputFrm.RichEdit.Lines.Add(outline); - outline := format('Adjusted R Squared = %5.3f',[AdjR2]); - OutputFrm.RichEdit.Lines.Add(outline); - OutputFrm.RichEdit.Lines.Add(''); - outline := format('Std. Error of Estimate = %10.3f',[StdErrEst]); - OutputFrm.RichEdit.Lines.Add(outline); - OutputFrm.RichEdit.Lines.Add(''); - OutputFrm.RichEdit.Lines.Add('Variable Beta B Std.Error t Prob.>t'); - df1 := 1.0; - sum := 0.0; - for i := 0 to Nentered - 2 do + end; + end; // check for interaction variables + + // check for covariates + if NCovIndep > 0 then + begin + for i := 0 to NCovIndep-1 do + begin + if cellstring = CovariateCode.Items.Strings[i] then // matched! begin - SSx := (totalobs-1) * Vars[i+1]; - sum := sum + B[i] * means[i+1]; - if invmatrix[i,i] > 1.0e-15 then - begin - StdErrB := VarEst / (SSx * (1.0 / invmatrix[i,i])); - StdErrB := sqrt(StdErrB); - if StdErrB > 0.0 then F := B[i] / StdErrB else F := 0.0; - FProbF := probf(F*F,df1,df2); - end - else begin - StdErrB := 0.0; - F := 0.0; - FProbF := 0.0; - end; - cellstring := format('%10s',[Labels[i+1]]); - outline := format('%10s%10.3f%10.3f%10.3f%10.3f%10.3f', - [cellstring, Beta[i] ,B[i], StdErrB, F, FProbF]); - OutputFrm.RichEdit.Lines.Add(outline); + index := i; // index of covariate code + ColSelected[NEntered] := CovIndepPos[index]; + labelstr := format('%s',[CovariateCode.Items.Strings[index]]); + Labels[NEntered] := labelstr; + NEntered := NEntered + 1; + break; end; - constant := means[0] - sum; - outline := format('Constant = %10.3f',[constant]); - OutputFrm.RichEdit.Lines.Add(outline); - TypeIISS[block] := R2 * SST; - OutputFrm.RichEdit.Lines.Add('WITHIN SUBJECT EFFECT:'); - outline := format('SS for %-10s = %10.3f',[effstr,TypeIISS[block]]); - OutputFrm.RichEdit.Lines.Add(outline); - outline := format('SS TOTAL = %10.3f',[SST]); - OutputFrm.RichEdit.Lines.Add(outline); - OutputFrm.ShowModal; + end; end; - totalss := 0.0; - totaldf := 0.0; - for i := 0 to noblocks - 1 do // add sums of squares for within effects - begin - if TypeIISS[i] < 0.0 then continue; - totalss := totalss + TypeIISS[i]; - totaldf := totaldf + TypeIIDF1[i]; - end; - sserrwithin := sswithin - totalss; - dferrwithin := dfwithin - totaldf; - mserrwithin := sserrwithin / dferrwithin; - OutputFrm.RichEdit.Lines.Clear; - OutputFrm.RichEdit.Lines.Add(' SUMMARY OF WITHIN SUBJECT EFFECTS'); - outline := 'SOURCE DF SS MS F PROB.>F'; - OutputFrm.RichEdit.Lines.Add(outline); - OutputFrm.RichEdit.Lines.Add(''); - outline := format('%-19s %3.0f %9.3f',['Within Subjects',dfwithin, sswithin]); - OutputFrm.RichEdit.Lines.Add(outline); - for i := 0 to noblocks - 1 do - begin - if TypeIISS[i] < 0.0 then continue; - TypeIIMS[i] := TypeIISS[i] / TypeIIDF1[i]; - TypeIIF[i] := TypeIIMS[i] / mserrwithin; - TypeIIDF2[i] := dferrwithin; - TypeIIProb[i] := probf(TypeIIF[i],TypeIIDF1[i],TypeIIDF2[i]); - outline := format('%19s %3.0f %9.3f %9.3f %9.3f %9.3f', - [IndOrderBox.Items.Strings[i],TypeIIDF1[i],TypeIISS[i],TypeIIMS[i], - TypeIIF[i],TypeIIProb[i]]); - OutputFrm.RichEdit.Lines.Add(outline); - end; - outline := format('%19s %3.0f %9.3f %9.3f',['Error Within', dferrwithin, - sserrwithin, mserrwithin]); - OutputFrm.RichEdit.Lines.Add(outline); - outline := format('%19s %3d %9.3f',['TOTAL',totalobs-1,SST]); - OutputFrm.RichEdit.Lines.Add(outline); - OutputFrm.ShowModal; + // do reg analysis and save sum of squares + RegAnal(NEntered, AReport); + R := sqrt(R2); + df1 := Nentered - 1; // no. of independent variables + TypeIDF1[block] := df1; + df2 := totalobs - df1 - 1; // N - no. independent - 1 + SSt := (totalobs-1) * Vars[0]; + SSres := SSt * (1.0 - R2); + VarEst := SSres / df2; - // clean up the heap - TypeIIProb := nil; - TypeIIF := nil; - TypeIProb := nil; - TypeIF := nil; - TypeIIDF2 := nil; - TypeIIDF1 := nil; - TypeIDF2 := nil; - TypeIDF1 := nil; - TypeIIMS := nil; - TypeIMS := nil; - TypeIISS := nil; - TypeISS := nil; + if (VarEst > 0.0) then + StdErrEst := sqrt(VarEst) + else + begin + ShowMessage('ERROR! Error in computing variance estimate.'); + StdErrEst := 0.0; + end; + + if (R2 < 1.0) and (df2 > 0.0) then + F := (R2 / df1) / ((1.0-R2)/ df2) + else + F := 0.0; + FProbF := probf(F,df1,df2); + AdjR2 := 1.0 - (1.0 - R2) * (totalobs - 1) / df2; + + AReport.Add(' R R2 F Prob. > F DF1 DF2 '); + AReport.Add('-------- ---------- ---------- ---------- ----- -----'); + AReport.Add('%8.3f %10.3f %10.3f %10.3f %5.0f %5.0f', [R, R2, F, FProbF, df1, df2]); + AReport.Add('Adjusted R Squared: %10.3f', [AdjR2]); + AReport.Add(''); + AReport.Add('Std. Error of Estimate: %10.3f', [StdErrEst]); + AReport.Add(''); + AReport.Add('Variable Beta B Std.Error t Prob. > t '); + AReport.Add('---------- ---------- ---------- ---------- ---------- ----------'); + + df1 := 1.0; + sum := 0.0; + for i := 0 to Nentered - 2 do + begin + SSx := (totalobs-1) * Vars[i+1]; + sum := sum + B[i] * means[i+1]; + if invmatrix[i,i] > 1.0e-15 then + begin + StdErrB := VarEst / (SSx * (1.0 / invmatrix[i,i])); + StdErrB := sqrt(StdErrB); + if StdErrB > 0.0 then F := B[i] / StdErrB else F := 0.0; + FProbF := probf(F*F,df1,df2); + end + else begin + StdErrB := 0.0; + F := 0.0; + FProbF := 0.0; + end; + cellstring := Format('%10s', [Labels[i+1]]); + AReport.Add('%10s %10.3f %10.3f %10.3f %10.3f %10.3f', [cellstring, Beta[i] ,B[i], StdErrB, F, FProbF]); + end; + constant := means[0] - sum; + AReport.Add('Constant: %10.3f', [constant]); + TypeISS[block] := R2 * SST; + AReport.Add('BETWEEN SUBJECT EFFECT:'); + AReport.Add('SS for %-10s: %10.3f',[effstr,TypeISS[block]]); + AReport.Add('SS TOTAL: %10.3f',[SST]); + AReport.Add(''); + AReport.Add('======================================================================================='); + AReport.Add(''); + end; + + // Summarize between subject effects + totalss := 0.0; + totaldf := 0.0; + for i := 0 to noblocks - 1 do + begin + if TypeISS[i] < 0.0 then continue; + if betweenblock = i then + begin + ssbetween := TypeISS[i]; + dfbetween := TypeIDF1[i]; + end + else + begin + totalss := totalss + TypeISS[i]; + totaldf := totaldf + TypeIDF1[i]; + end; + end; + sserrbetween := ssbetween - totalss; + dferrbetween := dfbetween - totaldf; + mserrbetween := sserrbetween / dferrbetween; + + AReport.Add('SUMMARY OF BETWEEN SUBJECT EFFECTS'); + AReport.Add('SOURCE DF SS MS F Prob > F'); + AReport.Add('-------------------- ---- ---------- ---------- ---------- --------'); + AReport.Add('%-20s %4.0f %10.3f', ['Between Subjects', dfbetween, ssbetween]); + for i := 0 to noblocks - 1 do + begin + if TypeISS[i] < 0.0 then continue; + if betweenblock = i then continue; // already done above + TypeIMS[i] := TypeISS[i] / TypeIDF1[i]; + TypeIF[i] := TypeIMS[i] / mserrbetween; + TypeIDF2[i] := dferrbetween; + TypeIProb[i] := probf(TypeIF[i],TypeIDF1[i],TypeIDF2[i]); + AReport.Add('%20s %4.0f %10.3f %10.3f %10.3f %10.3f', + [IndOrderBox.Items[i], TypeIDF1[i], TypeISS[i], TypeIMS[i], TypeIF[i], TypeIProb[i]] + ); + end; + AReport.Add('%20s %4.0f %10.3f %10.3f', ['Error Between', dferrbetween, sserrbetween, mserrbetween]); + AReport.Add(''); + AReport.Add('======================================================================================='); + AReport.Add(''); + + // Now, get within subject effects + sswithin := SST - SSbetween; + dfwithin := totalobs - dfbetween - 1; + for block := 0 to noblocks - 1 do + begin + ColSelected[0] := ReptDepPos[0]; + Labels[0] := GenLabels[1]; + NEntered := 1; + cellstring := IndOrderBox.Items.Strings[block]; + effstr := cellstring; + j := Pos('IR',cellstring); + if j = 0 then continue; // only select those for rep. treatments or interactions + + // check for treatments + if NReptDep > 0 then + begin // look for 'IR' in cellstring + labelstr := copy(cellstring,0,2); + if labelstr = 'IR' then // repeated treatment vectors were generated + begin + for i := 0 to NReptDep - 2 do + begin + ColSelected[NEntered] := ReptTrtPos[i]; + Labels[NEntered] := GenLabels[ReptTrtPos[i]]; + NEntered := NEntered + 1; + end; + end; + end; + + // check for interactions next + if NoInterDefs > 0 then + begin + for i := 0 to NoInterDefs-1 do + begin + if cellstring = InteractList.Items.Strings[i] then + begin + for j := 0 to NInteractVecs[i]-1 do + begin + ColSelected[NEntered] := InteractPos[i] + j; + labelstr := format('%s%d_%d',['IA',i+1,j+1]); + Labels[NEntered] := labelstr; + NEntered := NEntered + 1; + end; + break; + end; + end; + end; // check for interaction variables + + // do reg analysis and save sum of squares + if NEntered < 2 then continue; + RegAnal(NEntered, AReport); + R := sqrt(R2); + df1 := Nentered - 1; // no. of independent variables + TypeIIDF1[block] := df1; + df2 := totalobs - df1 - 1; // N - no. independent - 1 + SSt := (totalobs-1) * Vars[0]; + SSres := SSt * (1.0 - R2); + VarEst := SSres / df2; + if (VarEst > 0.0) then + StdErrEst := sqrt(VarEst) + else + begin + MessageDlg('Error in computing variance estimate.', mtError,[mbOK], 0); + StdErrEst := 0.0; + end; + if (R2 < 1.0) and (df2 > 0.0) then + F := (R2 / df1) / ((1.0-R2)/ df2) + else + F := 0.0; + FProbF := probf(F,df1,df2); + AdjR2 := 1.0 - (1.0 - R2) * (totalobs - 1) / df2; + + AReport.Add(' R R2 F Prob. > F DF1 DF2 '); + AReport.Add('-------- ---------- ---------- ---------- ----- -----'); + AReport.Add('%8.3f %10.3f %10.3f %10.3f %5.0f %5.0f', [R, R2, F, FProbF, df1, df2]); + AReport.Add(''); + AReport.Add('Adjusted R Squared: %10.3f', [AdjR2]); + AReport.Add('Std. Error of Estimate: %10.3f', [StdErrEst]); + AReport.Add(''); + AReport.Add('Variable Beta B Std.Error t Prob. > t '); + AReport.Add('---------- ---------- ---------- ---------- ---------- ----------'); + + df1 := 1.0; + sum := 0.0; + for i := 0 to Nentered - 2 do + begin + SSx := (totalobs-1) * Vars[i+1]; + sum := sum + B[i] * means[i+1]; + if invmatrix[i,i] > 1.0e-15 then + begin + StdErrB := VarEst / (SSx * (1.0 / invmatrix[i,i])); + StdErrB := sqrt(StdErrB); + if StdErrB > 0.0 then F := B[i] / StdErrB else F := 0.0; + FProbF := probf(F*F,df1,df2); + end + else begin + StdErrB := 0.0; + F := 0.0; + FProbF := 0.0; + end; + cellstring := Format('%10s', [Labels[i+1]]); + AReport.Add('%10s %10.3f %10.3f %10.3f %10.3f %10.3f', [cellstring, Beta[i] ,B[i], StdErrB, F, FProbF]); + end; + constant := means[0] - sum; + AReport.Add('Constant: %10.3f', [constant]); + + TypeIISS[block] := R2 * SST; + AReport.Add('BETWEEN SUBJECT EFFECT:'); + AReport.Add('SS for %-10s: %10.3f',[effstr, TypeIISS[block]]); + AReport.Add('SS TOTAL: %10.3f',[SST]); + AReport.Add(''); + AReport.Add('======================================================================================='); + AReport.Add(''); + end; + + totalss := 0.0; + totaldf := 0.0; + for i := 0 to noblocks - 1 do // add sums of squares for within effects + begin + if TypeIISS[i] < 0.0 then continue; + totalss := totalss + TypeIISS[i]; + totaldf := totaldf + TypeIIDF1[i]; + end; + sserrwithin := sswithin - totalss; + dferrwithin := dfwithin - totaldf; + mserrwithin := sserrwithin / dferrwithin; + + AReport.Add(' SUMMARY OF WITHIN SUBJECT EFFECTS'); + AReport.Add('SOURCE DF SS MS F Prob > F'); + AReport.Add('-------------------- ---- ---------- ---------- ---------- --------'); + AReport.Add('%-20s %4.0f %10.3f', ['Within Subjects', dfwithin, sswithin]); + for i := 0 to noblocks - 1 do + begin + if TypeIISS[i] < 0.0 then continue; + TypeIIMS[i] := TypeIISS[i] / TypeIIDF1[i]; + TypeIIF[i] := TypeIIMS[i] / mserrwithin; + TypeIIDF2[i] := dferrwithin; + TypeIIProb[i] := probf(TypeIIF[i],TypeIIDF1[i],TypeIIDF2[i]); + AReport.Add('%20s %4.0f %10.3f %10.3f %10.3f %10.3f', + [IndOrderBox.Items.Strings[i],TypeIIDF1[i],TypeIISS[i],TypeIIMS[i],TypeIIF[i],TypeIIProb[i]] + ); + end; + AReport.Add('%20s %4.0f %10.3f %10.3f', ['Error Within', dferrwithin, sserrwithin, mserrwithin]); + AReport.Add('%20s %4d %10.3f', ['TOTAL', totalobs-1, SST]); + + AReport.Add(''); + AReport.Add('======================================================================================='); + AReport.Add(''); + + // clean up the heap + TypeIIProb := nil; + TypeIIF := nil; + TypeIProb := nil; + TypeIF := nil; + TypeIIDF2 := nil; + TypeIIDF1 := nil; + TypeIDF2 := nil; + TypeIDF1 := nil; + TypeIIMS := nil; + TypeIMS := nil; + TypeIISS := nil; + TypeISS := nil; end; function TGLMFrm.CntIntActVecs(linestr: string): integer; @@ -3337,6 +3409,27 @@ cleanup: raa := nil; end; +procedure TGLMFrm.UpdateBtnStates; +begin + ContDepInBtn.Enabled := VarList.ItemIndex > -1; + ContDepOutBtn.Enabled := DepContList.ItemIndex > -1; + + CatDepInBtn.Enabled := VarList.ItemIndex > -1; + CatDepOutBtn.Enabled := DepCatList.ItemIndex > -1; + + ReptDepInBtn.Enabled := AnySelected(VarList); + ReptDepOutBtn.Enabled := RepeatList.ItemIndex > -1; + + FixedIndepInBtn.Enabled := AnySelected(VarList); + FixedIndepOutBtn.Enabled := FixedList.ItemIndex > -1; + + RndIndepInBtn.Enabled := VarList.ItemIndex > -1; + RndIndepOutBtn.Enabled := RandomList.ItemIndex > -1; + + CovInBtn.Enabled := VarList.ItemIndex > -1; + CovOutBtn.Enabled := CovariateList.ItemIndex > -1; +end; + initialization {$I glmunit.lrs}