2020-04-18 20:50:34 +00:00
|
|
|
// File for testing: CompRelData.laz, use all variables
|
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
unit CompRelUnit;
|
|
|
|
|
|
|
|
{$mode objfpc}{$H+}
|
2020-11-23 17:03:40 +00:00
|
|
|
{$WARN 6058 off : Call to subroutine "$1" marked as inline is not inlined}
|
2020-03-30 18:01:44 +00:00
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
uses
|
2020-11-23 17:03:40 +00:00
|
|
|
Classes, SysUtils, Forms, Controls, Graphics, StdCtrls, Buttons, ExtCtrls,
|
|
|
|
MainUnit, Globals, MatrixLib, DictionaryUnit, BasicStatsReportFormUnit;
|
2020-03-30 18:01:44 +00:00
|
|
|
|
|
|
|
type
|
|
|
|
|
2020-11-23 17:03:40 +00:00
|
|
|
{ TCompRelForm }
|
2020-03-30 18:01:44 +00:00
|
|
|
|
2020-11-23 17:03:40 +00:00
|
|
|
TCompRelForm = class(TBasicStatsReportForm)
|
|
|
|
Bevel1: TBevel;
|
2020-03-30 18:01:44 +00:00
|
|
|
InBtn: TBitBtn;
|
|
|
|
OutBtn: TBitBtn;
|
|
|
|
AllBtn: TBitBtn;
|
|
|
|
RMatChk: TCheckBox;
|
|
|
|
GridScrChk: TCheckBox;
|
|
|
|
GroupBox1: TGroupBox;
|
|
|
|
Label1: TLabel;
|
|
|
|
Label2: TLabel;
|
|
|
|
ItemList: TListBox;
|
|
|
|
Label3: TLabel;
|
|
|
|
Label4: TLabel;
|
|
|
|
WeightList: TListBox;
|
|
|
|
RelList: TListBox;
|
|
|
|
VarList: TListBox;
|
|
|
|
procedure AllBtnClick(Sender: TObject);
|
|
|
|
procedure InBtnClick(Sender: TObject);
|
2020-10-26 18:00:52 +00:00
|
|
|
procedure ItemListSelectionChange(Sender: TObject; {%H-}User: boolean);
|
2020-03-30 18:01:44 +00:00
|
|
|
procedure OutBtnClick(Sender: TObject);
|
|
|
|
procedure RelListClick(Sender: TObject);
|
|
|
|
procedure WeightListClick(Sender: TObject);
|
2020-11-23 17:03:40 +00:00
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
private
|
2020-11-23 17:03:40 +00:00
|
|
|
|
|
|
|
protected
|
|
|
|
procedure AdjustConstraints; override;
|
|
|
|
procedure Compute; override;
|
|
|
|
procedure UpdateBtnStates; override;
|
|
|
|
function Validate(out AMsg: String; out AControl: TWinControl): Boolean; override;
|
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
public
|
2020-11-23 17:03:40 +00:00
|
|
|
procedure Reset; override;
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
var
|
2020-11-23 17:03:40 +00:00
|
|
|
CompRelForm: TCompRelForm;
|
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
|
|
|
|
implementation
|
|
|
|
|
2020-11-23 17:03:40 +00:00
|
|
|
{$R *.lfm}
|
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
uses
|
2020-11-23 17:03:40 +00:00
|
|
|
Dialogs, Math,
|
|
|
|
Utils, GridProcs;
|
2020-04-18 20:50:34 +00:00
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
|
2020-11-23 17:03:40 +00:00
|
|
|
{ TCompRelForm }
|
2020-03-30 18:01:44 +00:00
|
|
|
|
2020-11-23 17:03:40 +00:00
|
|
|
procedure TCompRelForm.AdjustConstraints;
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
2020-11-23 17:03:40 +00:00
|
|
|
inherited;
|
2020-03-30 18:01:44 +00:00
|
|
|
|
2020-11-23 17:03:40 +00:00
|
|
|
RelList.Width := Max(Label3.Width, Label4.Width);
|
|
|
|
WeightList.Width := RelList.Width;
|
2020-03-30 18:01:44 +00:00
|
|
|
|
2021-01-03 23:50:51 +00:00
|
|
|
ParamsPanel.Constraints.MinWidth := MaxValueI([
|
2020-11-23 17:03:40 +00:00
|
|
|
GroupBox1.Width,
|
|
|
|
4*CloseBtn.Width + 3*CloseBtn.BorderSpacing.Left,
|
|
|
|
Max(Label1.Width, Label2.Width)*2 + 2*RelList.Width +
|
|
|
|
AllBtn.Width + 2*VarList.BorderSpacing.Right + 2*RelList.BorderSpacing.Right]);
|
2020-03-30 18:01:44 +00:00
|
|
|
|
2020-11-23 17:03:40 +00:00
|
|
|
ParamsPanel.Constraints.MinHeight := OutBtn.Top + 4*OutBtn.Height + 3*OutBtn.BorderSpacing.Bottom +
|
|
|
|
VarList.BorderSpacing.Bottom + GroupBox1.Height +
|
|
|
|
ButtonBevel.Height + CloseBtn.BorderSpacing.Top + CloseBtn.Height;
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
|
2020-11-23 17:03:40 +00:00
|
|
|
procedure TCompRelForm.AllBtnClick(Sender: TObject);
|
2020-03-30 18:01:44 +00:00
|
|
|
var
|
2020-04-21 20:45:15 +00:00
|
|
|
i: integer;
|
2020-04-18 20:50:34 +00:00
|
|
|
cellstring : string;
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
2020-04-18 20:50:34 +00:00
|
|
|
cellstring := '1.0';
|
|
|
|
for i := 1 to VarList.Items.Count do
|
|
|
|
begin
|
|
|
|
ItemList.Items.Add(VarList.Items[i-1]);
|
|
|
|
RelList.Items.Add(cellstring);
|
|
|
|
WeightList.Items.Add(cellstring);
|
|
|
|
end;
|
|
|
|
VarList.Clear;
|
2020-11-23 17:03:40 +00:00
|
|
|
UpdateBtnStates;
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
|
2020-11-23 17:03:40 +00:00
|
|
|
|
|
|
|
procedure TCompRelForm.Compute;
|
2020-03-30 18:01:44 +00:00
|
|
|
var
|
2020-04-18 20:50:34 +00:00
|
|
|
errorcode: boolean = false;
|
2020-11-23 17:03:40 +00:00
|
|
|
Rmat: DblDyneMat = nil;
|
|
|
|
RelMat: DblDyneMat = nil;
|
|
|
|
Weights: DblDyneVec = nil;
|
|
|
|
Reliabilities: DblDyneVec = nil;
|
|
|
|
VectProd: DblDyneVec = nil;
|
|
|
|
means: DblDyneVec = nil;
|
|
|
|
variances: DblDyneVec = nil;
|
|
|
|
stddevs: DblDyneVec = nil;
|
|
|
|
ColNoSelected: IntDyneVec = nil;
|
|
|
|
RowLabels: StrDyneVec = nil;
|
2020-04-21 20:45:15 +00:00
|
|
|
cellstring: string;
|
2020-04-18 20:50:34 +00:00
|
|
|
title: string;
|
2020-11-23 17:03:40 +00:00
|
|
|
i, j, NoVars, count, col: integer;
|
|
|
|
CompRel, numerator, denominator, compscore: double;
|
2020-04-18 20:50:34 +00:00
|
|
|
lReport: TStrings;
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
2020-11-23 17:03:40 +00:00
|
|
|
SetLength(Rmat, NoVariables+1,NoVariables+1);
|
|
|
|
SetLength(RelMat, NoVariables+1, NoVariables+1);
|
|
|
|
SetLength(Weights, NoVariables);
|
|
|
|
SetLength(Reliabilities, NoVariables);
|
|
|
|
SetLength(VectProd, NoVariables);
|
|
|
|
SetLength(means, NoVariables);
|
|
|
|
SetLength(variances, NoVariables);
|
|
|
|
SetLength(stddevs, NoVariables);
|
|
|
|
|
|
|
|
// Get selected variables' column numbers
|
2020-03-30 18:01:44 +00:00
|
|
|
NoVars := ItemList.Items.Count;
|
2020-11-23 17:03:40 +00:00
|
|
|
SetLength(RowLabels, NoVars);
|
|
|
|
Setlength(ColNoSelected, NoVars);
|
2020-04-18 20:58:47 +00:00
|
|
|
for i := 0 to NoVars-1 do
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
2020-11-23 17:03:40 +00:00
|
|
|
RowLabels[i] := ItemList.Items[i];
|
|
|
|
ColNoSelected[i] := GetVariableIndex(OS3MainFrm.DataGrid, RowLabels[i]);
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
count := NoCases;
|
|
|
|
|
2020-04-18 20:50:34 +00:00
|
|
|
lReport := TStringList.Create;
|
|
|
|
try
|
|
|
|
lReport.Add('COMPOSITE TEST RELIABILITY');
|
|
|
|
lReport.Add('');
|
2020-11-23 17:03:40 +00:00
|
|
|
lReport.Add('File analyzed: ' + OS3MainFrm.FileNameEdit.Text);
|
2020-04-18 20:50:34 +00:00
|
|
|
lReport.Add('');
|
|
|
|
|
|
|
|
// get correlation matrix
|
2020-11-23 17:03:40 +00:00
|
|
|
Correlations(NoVars, ColNoSelected, Rmat, means, variances, stddevs, errorcode, count);
|
2020-04-18 20:50:34 +00:00
|
|
|
|
|
|
|
if errorcode then
|
2020-11-23 17:03:40 +00:00
|
|
|
begin
|
|
|
|
ErrorMsg('Zero variance found for a variable.');
|
|
|
|
exit;
|
|
|
|
end;
|
2020-04-18 20:50:34 +00:00
|
|
|
|
|
|
|
if RmatChk.Checked then
|
|
|
|
begin
|
|
|
|
title := 'Correlations Among Tests';
|
|
|
|
MatPrint(Rmat, NoVars, NoVars, title, RowLabels, RowLabels, count, lReport);
|
|
|
|
title := 'Means';
|
|
|
|
DynVectorPrint(means, NoVars, title, RowLabels, count, lReport);
|
|
|
|
title := 'Variances';
|
|
|
|
DynVectorPrint(variances, NoVars, title, RowLabels, count, lReport);
|
|
|
|
title := 'Standard Deviations';
|
|
|
|
DynVectorPrint(stddevs, NoVars, title, RowLabels, count, lReport);
|
|
|
|
end;
|
|
|
|
|
2020-04-18 20:58:47 +00:00
|
|
|
for i := 0 to NoVars do
|
|
|
|
for j := 0 to NoVars do
|
|
|
|
RelMat[i, j] := Rmat[i, j];
|
2020-04-18 20:50:34 +00:00
|
|
|
|
2020-04-18 20:58:47 +00:00
|
|
|
for i := 0 to NoVars-1 do
|
2020-04-18 20:50:34 +00:00
|
|
|
begin
|
2020-11-23 17:03:40 +00:00
|
|
|
Reliabilities[i] := StrToFloat(RelList.Items[i]);
|
2020-04-18 20:58:47 +00:00
|
|
|
RelMat[i, i] := Reliabilities[i];
|
2020-11-23 17:03:40 +00:00
|
|
|
Weights[i] := StrToFloat(WeightList.Items[i]);
|
2020-04-18 20:50:34 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
// get numerator and denominator of composite reliability
|
2020-04-18 20:58:47 +00:00
|
|
|
for i := 0 to NoVars-1 do
|
|
|
|
VectProd[i] := 0.0;
|
2020-04-18 20:50:34 +00:00
|
|
|
numerator := 0.0;
|
|
|
|
denominator := 0.0;
|
2020-04-18 20:58:47 +00:00
|
|
|
for i := 0 to NoVars-1 do
|
|
|
|
for j := 0 to NoVars-1 do
|
|
|
|
VectProd[i] := VectProd[i] + (Weights[i] * RelMat[j, i]);
|
|
|
|
for i := 0 to NoVars-1 do
|
|
|
|
numerator := numerator + (VectProd[i] * Weights[i]);
|
|
|
|
|
|
|
|
for i := 0 to NoVars-1 do
|
|
|
|
VectProd[i] := 0.0;
|
|
|
|
for i := 0 to NoVars-1 do
|
|
|
|
for j := 0 to NoVars-1 do
|
|
|
|
VectProd[i] := VectProd[i] + (Weights[i] * Rmat[j, i]);
|
|
|
|
for i := 0 to NoVars-1 do
|
|
|
|
denominator := denominator + VectProd[i] * Weights[i];
|
2020-04-18 20:50:34 +00:00
|
|
|
CompRel := numerator / denominator;
|
|
|
|
|
|
|
|
title := 'Test Weights';
|
|
|
|
DynVectorPrint(Weights, NoVars, title, RowLabels, count, lReport);
|
|
|
|
title := 'Test Reliabilities';
|
|
|
|
DynVectorPrint(Reliabilities, NoVars, title, RowLabels, count, lReport);
|
|
|
|
lReport.Add('Composite reliability: %6.3f', [CompRel]);
|
|
|
|
|
2020-11-23 17:03:40 +00:00
|
|
|
FReportFrame.DisplayReport(lReport);
|
2020-03-30 18:01:44 +00:00
|
|
|
|
2020-04-18 20:50:34 +00:00
|
|
|
if GridScrChk.Checked then
|
|
|
|
begin
|
|
|
|
cellstring := 'Composite';
|
2020-11-23 17:03:40 +00:00
|
|
|
col := GetVariableIndex(OS3MainFrm.DataGrid, cellString);
|
|
|
|
if col = -1 then
|
|
|
|
begin
|
|
|
|
col := NoVariables + 1;
|
|
|
|
DictionaryFrm.NewVar(col);
|
|
|
|
DictionaryFrm.DictGrid.Cells[1,col] := cellstring;
|
|
|
|
col := NoVariables;
|
|
|
|
OS3MainFrm.DataGrid.Cells[col,0] := cellstring;
|
|
|
|
col := NoVariables;
|
2020-11-23 17:45:40 +00:00
|
|
|
end else
|
|
|
|
begin
|
|
|
|
if MessageDlg('Overwrite variable "' + cellstring + '"?', mtConfirmation, [mbYes, mbNo], 0) <> mrYes then
|
|
|
|
exit;
|
2020-11-23 17:03:40 +00:00
|
|
|
end;
|
2020-04-18 20:50:34 +00:00
|
|
|
for i := 1 to NoCases do
|
|
|
|
begin
|
2020-11-23 17:03:40 +00:00
|
|
|
if not GoodRecord(OS3MainFrm.DataGrid, i, ColNoSelected) then
|
2020-04-18 20:58:47 +00:00
|
|
|
continue;
|
2020-04-18 20:50:34 +00:00
|
|
|
compscore := 0.0;
|
2020-04-18 20:58:47 +00:00
|
|
|
for j := 0 to NoVars-1 do
|
2020-11-23 17:03:40 +00:00
|
|
|
compscore := compscore + (Weights[j] * StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[ColNoSelected[j],i])));
|
2020-04-18 20:50:34 +00:00
|
|
|
OS3MainFrm.DataGrid.Cells[col,i] := FloatToStr(compscore);
|
|
|
|
end;
|
2020-11-23 17:03:40 +00:00
|
|
|
GridScrChk.Checked := false;
|
2020-04-18 20:50:34 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
finally
|
|
|
|
lReport.Free;
|
|
|
|
end;
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
|
2020-11-23 17:03:40 +00:00
|
|
|
|
|
|
|
procedure TCompRelForm.InBtnClick(Sender: TObject);
|
2020-03-30 18:01:44 +00:00
|
|
|
var
|
2020-04-18 20:50:34 +00:00
|
|
|
i: integer;
|
|
|
|
cellstring: string;
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
2020-04-18 20:50:34 +00:00
|
|
|
cellstring := '1.0';
|
2020-04-21 20:45:15 +00:00
|
|
|
i := 0;
|
2020-04-18 20:50:34 +00:00
|
|
|
while i < VarList.Items.Count do
|
|
|
|
begin
|
|
|
|
if VarList.Selected[i] then
|
|
|
|
begin
|
|
|
|
ItemList.Items.Add(VarList.Items[i]);
|
|
|
|
RelList.Items.Add(cellstring);
|
|
|
|
WeightList.Items.Add(cellstring);
|
|
|
|
VarList.Items.Delete(i);
|
|
|
|
i := 0;
|
|
|
|
end
|
|
|
|
else
|
|
|
|
inc(i);
|
|
|
|
end;
|
|
|
|
UpdateBtnStates;
|
|
|
|
end;
|
|
|
|
|
2020-11-23 17:03:40 +00:00
|
|
|
|
|
|
|
procedure TCompRelForm.ItemListSelectionChange(Sender: TObject; User: boolean);
|
2020-04-18 20:50:34 +00:00
|
|
|
begin
|
|
|
|
UpdateBtnStates;
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
|
2020-11-23 17:03:40 +00:00
|
|
|
|
|
|
|
procedure TCompRelForm.OutBtnClick(Sender: TObject);
|
2020-04-18 20:50:34 +00:00
|
|
|
var
|
|
|
|
i: Integer;
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
2020-04-21 20:45:15 +00:00
|
|
|
i := 0;
|
2020-04-18 20:50:34 +00:00
|
|
|
while i < ItemList.Items.Count do
|
|
|
|
begin
|
|
|
|
if ItemList.Selected[i] then
|
|
|
|
begin
|
|
|
|
VarList.Items.Add(ItemList.Items[i]);
|
|
|
|
ItemList.Items.Delete(i);
|
|
|
|
RelList.Items.Delete(i);
|
|
|
|
WeightList.Items.Delete(i);
|
|
|
|
i := 0;
|
|
|
|
end else
|
|
|
|
inc(i);
|
|
|
|
end;
|
|
|
|
UpdateBtnStates;
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
|
2020-11-23 17:03:40 +00:00
|
|
|
|
|
|
|
procedure TCompRelForm.RelListClick(Sender: TObject);
|
2020-03-30 18:01:44 +00:00
|
|
|
var
|
2020-04-18 20:50:34 +00:00
|
|
|
response: string;
|
|
|
|
index: integer;
|
|
|
|
begin
|
|
|
|
response := InputBox('Reliability', 'Reliability estimate: ', '1.0');
|
|
|
|
index := RelList.ItemIndex;
|
|
|
|
RelList.Items[index] := response;
|
|
|
|
end;
|
|
|
|
|
2020-11-23 17:03:40 +00:00
|
|
|
|
|
|
|
procedure TCompRelForm.Reset;
|
|
|
|
begin
|
|
|
|
inherited;
|
|
|
|
|
|
|
|
CollectVariableNames(OS3MainFrm.DataGrid, VarList.Items);
|
|
|
|
ItemList.Clear;
|
|
|
|
RelList.Clear;
|
|
|
|
WeightList.Clear;
|
|
|
|
UpdateBtnStates;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
procedure TCompRelForm.UpdateBtnStates;
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
2020-11-23 17:03:40 +00:00
|
|
|
inherited;
|
2020-04-18 20:50:34 +00:00
|
|
|
InBtn.Enabled := AnySelected(VarList);
|
|
|
|
OutBtn.Enabled := AnySelected(ItemList);
|
|
|
|
AllBtn.Enabled := VarList.Items.Count > 0;
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
|
2020-11-23 17:03:40 +00:00
|
|
|
|
|
|
|
function TCompRelForm.Validate(out AMsg: String; out AControl: TWinControl): Boolean;
|
|
|
|
begin
|
|
|
|
Result := false;
|
|
|
|
|
|
|
|
if ItemList.Count = 0 then
|
|
|
|
begin
|
|
|
|
AMsg := 'No items selected.';
|
|
|
|
AControl := VarList;
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
|
|
|
|
Result := true;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
procedure TCompRelForm.WeightListClick(Sender: TObject);
|
|
|
|
var
|
|
|
|
response: string;
|
|
|
|
index: integer;
|
|
|
|
begin
|
|
|
|
response := InputBox('Test Weight', 'Test weight:', '1.0');
|
|
|
|
index := WeightList.ItemIndex;
|
|
|
|
WeightList.Items.Strings[index] := response;
|
|
|
|
end;
|
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
|
|
|
|
end.
|
|
|
|
|