unit CochranQUnit; {$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, Buttons, ExtCtrls, MainUnit, Globals, FunctionsLib, BasicStatsReportFormUnit; type { TCochranQForm } TCochranQForm = class(TBasicStatsReportForm) InBtn: TBitBtn; Label2: TLabel; SelList: TListBox; OutBtn: TBitBtn; AllBtn: TBitBtn; Label1: TLabel; VarList: TListBox; procedure AllBtnClick(Sender: TObject); procedure InBtnClick(Sender: TObject); procedure OutBtnClick(Sender: TObject); procedure SelListDblClick(Sender: TObject); procedure VarListDblClick(Sender: TObject); procedure VarListSelectionChange(Sender: TObject; {%H-}User: boolean); private protected procedure AdjustConstraints; override; procedure Compute; override; procedure UpdateBtnStates; override; function Validate(out AMsg: String; out AControl: TWinControl): Boolean; override; public procedure Reset; override; end; var CochranQForm: TCochranQForm; implementation {$R *.lfm} uses Utils, GridProcs; { TCochranQForm } procedure TCochranQForm.AdjustConstraints; begin inherited; ParamsPanel.Constraints.MinWidth := 4*CloseBtn.Width + 3*CloseBtn.BorderSpacing.Left; ParamsPanel.Constraints.MinHeight := AllBtn.Top + AllBtn.Height + ButtonBevel.Height + CloseBtn.BorderSpacing.Top + CloseBtn.Height; end; procedure TCochranQForm.AllBtnClick(Sender: TObject); var index: integer; begin for index := 0 to VarList.Items.Count - 1 do SelList.Items.Add(VarList.Items[index]); UpdateBtnStates; end; procedure TCochranQForm.Compute; var i, j, col: integer; selCount: Integer; ColNoSelected: IntDyneVec = nil; R1, L1, L2, C1, g1, Q, g2, chiprob: double; lReport: TStrings; begin selCount := SelList.Items.Count; SetLength(ColNoSelected, selCount); // Get column numbers of variables selected for i := 0 to selCount-1 do ColNoSelected[i] := GetVariableIndex(OS3MainFrm.DataGrid, SelList.Items[i]); // Calculate results C1 := 0.0; R1 := 0.0; L1 := 0.0; L2 := 0.0; g1 := 0.0; g2 := 0.0; for i := 1 to NoCases do begin if (not GoodRecord(OS3MainFrm.DataGrid, i, ColNoSelected)) then continue; for j := 0 to selCount-1 do begin col := ColNoSelected[j]; R1 := R1 + StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[col, i])); end; L1 := L1 + R1; L2 := L2 + (R1 * R1); R1 := 0.0; end; for j := 0 to selCount-1 do begin for i := 1 to NoCases do begin if (not GoodRecord(OS3MainFrm.DataGrid, i, ColNoSelected)) then continue; col := ColNoSelected[j]; C1 := C1 + StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[col, i])); end; g1 := g1 + C1; g2 := g2 + (C1 * C1); C1 := 0.0; end; if (selCount * L1 - L2) > 0.0 then begin Q := ((selCount - 1) * ((selCount * g2) - (g1 * g1))) / ((selCount * L1) - L2); chiProb := 1.0 - ChiSquaredProb(Q, selCount - 1); end else begin Q := 0.0; chiProb := 1.0; ErrorMsg('Error in obtaining Q and the probability.'); end; //present results lReport := TStringList.Create; try lReport.Add('COCHRAN Q TEST FOR RELATED SAMPLES'); lReport.Add('See pages 161-166 in S. Siegel: Nonparametric Statistics for the Behavioral Sciences'); lReport.Add('McGraw-Hill Book Company, New York, 1956'); lReport.Add(''); lReport.Add('Cochran Q Statistic: %.3f', [Q]); lReport.Add('which is distributed as chi-square'); lReport.Add('with %d degrees of freedum and probability %.4f', [selCount-1, chiProb]); FReportFrame.DisplayReport(lReport); finally lReport.Free; end; end; procedure TCochranQForm.InBtnClick(Sender: TObject); var i: integer; begin i := 0; while i < VarList.Items.Count do begin if VarList.Selected[i] then begin SelList.Items.Add(VarList.Items[i]); VarList.Items.Delete(i); i := 0; end else inc(i); end; UpdateBtnStates; end; procedure TCochranQForm.OutBtnClick(Sender: TObject); var i: integer; begin i := 0; while i < SelList.Items.Count do begin if SelList.Selected[i] then begin VarList.Items.Add(SelList.Items[i]); SelList.Items.Delete(i); i := 0; end else inc(i); end; UpdateBtnStates; end; procedure TCochranQForm.Reset; var i: integer; begin inherited; VarList.Clear; SelList.Clear; for i := 1 to NoVariables do VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]); UpdateBtnStates; end; procedure TCochranQForm.SelListDblClick(Sender: TObject); var index: Integer; begin index := SelList.ItemIndex; if index > -1 then begin VarList.Items.Add(SelList.Items[index]); SelList.Items.Delete(index); UpdateBtnStates; end; end; procedure TCochranQForm.UpdateBtnStates; begin inherited; InBtn.Enabled := AnySelected(VarList); OutBtn.Enabled := AnySelected(SelList); AllBtn.Enabled := VarList.Items.Count > 0; end; function TCochranQForm.Validate(out AMsg: String; out AControl: TWinControl): Boolean; begin Result := false; if SelList.Items.Count = 0 then begin AMsg := 'No variable(s) selected.'; AControl := VarList; exit; end; Result := true; end; procedure TCochranQForm.VarListDblClick(Sender: TObject); var index: Integer; begin index := VarList.ItemIndex; if index > -1 then begin SelList.Items.Add(VarList.Items[index]); Varlist.Items.Delete(index); UpdateBtnStates; end; end; procedure TCochranQForm.VarListSelectionChange(Sender: TObject; User: boolean); begin UpdateBtnStates; end; end.