Files
lazarus-ccr/applications/lazstats/source/forms/analysis/multiple_regression/wlsunit.pas

964 lines
31 KiB
ObjectPascal
Raw Normal View History

unit WLSUnit;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
StdCtrls, Buttons, ExtCtrls,
Globals, MainUnit, DictionaryUnit, FunctionsLib, Matrixlib, PlotXYUnit,
OutputUnit, DataProcs, BlankFrmUnit, ContextHelpUnit;
type
{ TWLSFrm }
TWLSFrm = class(TForm)
Bevel1: TBevel;
DepInBtn: TBitBtn;
DepOutBtn: TBitBtn;
HelpBtn: TButton;
IndInBtn: TBitBtn;
IndOutBtn: TBitBtn;
WghtInBtn: TBitBtn;
WghtOutBtn: TBitBtn;
ResetBtn: TButton;
ComputeBtn: TButton;
CloseBtn: TButton;
OLSChk: TCheckBox;
PlotChk: TCheckBox;
RegResChk: TCheckBox;
SaveChk: TCheckBox;
WeightChk: TCheckBox;
OriginChk: TCheckBox;
UserWghtsChk: TCheckBox;
Origin2Chk: TCheckBox;
DepVarEdit: TEdit;
WghtVarEdit: TEdit;
GroupBox1: TGroupBox;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
IndVarList: TListBox;
VarList: TListBox;
procedure ComputeBtnClick(Sender: TObject);
procedure DepInBtnClick(Sender: TObject);
procedure DepOutBtnClick(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure HelpBtnClick(Sender: TObject);
procedure IndInBtnClick(Sender: TObject);
procedure IndOutBtnClick(Sender: TObject);
procedure ResetBtnClick(Sender: TObject);
procedure VarListSelectionChange(Sender: TObject; User: boolean);
procedure WghtInBtnClick(Sender: TObject);
procedure WghtOutBtnClick(Sender: TObject);
procedure PredictIt(ColNoSelected : IntDyneVec; NoVars : integer;
Means, StdDevs, BetaWeights : DblDyneVec;
StdErrEst : double; NoIndepVars : integer);
procedure PlotXY(Xpoints, Ypoints, UpConf, LowConf : DblDyneVec;
ConfBand, Xmean, Ymean, R, Slope, Intercept : double;
Xmax, Xmin, Ymax, Ymin : double;
N : integer; XLabel, YLabel : string);
private
{ private declarations }
FAutoSized: Boolean;
procedure UpdateBtnStates;
public
{ public declarations }
end;
var
WLSFrm: TWLSFrm;
implementation
uses
Math;
{ TWLSFrm }
procedure TWLSFrm.ResetBtnClick(Sender: TObject);
VAR i : integer;
begin
VarList.Clear;
for i := 0 to NoVariables - 1 do
VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i+1,0]);
IndVarList.Clear;
DepVarEdit.Text := '';
WghtVarEdit.Text := '';
DepInBtn.Enabled := true;
DepOutBtn.Enabled := false;
IndInBtn.Enabled := true;
IndOutBtn.Enabled := false;
WghtInBtn.Enabled := true;
WghtOutBtn.Enabled := false;
OLSChk.Checked := true;
PlotChk.Checked := true;
RegResChk.Checked := true;
WeightChk.Checked := true;
UserWghtsChk.Checked := false;
OriginChk.Checked := true;
Origin2Chk.Checked := true;
end;
procedure TWLSFrm.VarListSelectionChange(Sender: TObject; User: boolean);
begin
UpdateBtnStates;
end;
procedure TWLSFrm.WghtInBtnClick(Sender: TObject);
var
index: integer;
begin
index := VarList.ItemIndex;
if (index > -1) and (WghtVarEdit.Text = '') then
begin
WghtVarEdit.Text := VarList.Items[index];
VarList.Items.Delete(index);
end;
UpdateBtnStates;
end;
procedure TWLSFrm.WghtOutBtnClick(Sender: TObject);
begin
if (WghtVarEdit.Text <> '') then
begin
VarList.Items.Add(WghtVarEdit.Text);
WghtVarEdit.Text := '';
end;
UpdateBtnStates;
end;
procedure TWLSFrm.FormActivate(Sender: TObject);
var
w: Integer;
begin
if FAutoSized then
exit;
w := MaxValue([HelpBtn.Width, ResetBtn.Width, ComputeBtn.Width, CloseBtn.Width]);
HelpBtn.Constraints.MinWidth := w;
ResetBtn.Constraints.MinWidth := w;
ComputeBtn.Constraints.MinWidth := w;
CloseBtn.Constraints.MinWidth := w;
Constraints.MinWidth := Width;
Constraints.MinHeight := Height;
FAutoSized := True;
end;
procedure TWLSFrm.FormCreate(Sender: TObject);
begin
Assert(OS3MainFrm <> nil);
if BlankFrm = nil then Application.CreateForm(TBlankFrm, BlankFrm);
if DictionaryFrm = nil then Application.CreateForm(TDictionaryFrm, DictionaryFrm);
end;
procedure TWLSFrm.FormShow(Sender: TObject);
begin
ResetBtnClick(self);
end;
procedure TWLSFrm.HelpBtnClick(Sender: TObject);
begin
if ContextHelpForm = nil then Application.CreateForm(TContextHelpForm, ContextHelpForm);
ContextHelpForm.HelpMessage((Sender as TButton).tag);
end;
procedure TWLSFrm.IndInBtnClick(Sender: TObject);
var
i: integer;
begin
i := 0;
while (i < VarList.Items.Count) do
begin
if (VarList.Selected[i]) then
begin
IndVarList.Items.Add(VarList.Items[i]);
VarList.Items.Delete(i);
i := 0;
end else
inc(i);
end;
UpdateBtnStates;
end;
procedure TWLSFrm.IndOutBtnClick(Sender: TObject);
var
i: integer;
begin
i := 0;
while (i < IndVarList.Items.Count) do
begin
if IndVarlist.Selected[i] then
begin
VarList.Items.Add(IndVarList.Items[i]);
IndVarlist.Items.Delete(i);
i := 0;
end else
inc(i);
end;
UpdateBtnStates;
end;
procedure TWLSFrm.DepInBtnClick(Sender: TObject);
var
index: integer;
begin
index := VarList.ItemIndex;
if (index > -1) and (DepVarEdit.Text = '') then
begin
DepVarEdit.Text := VarList.Items[index];
VarList.Items.Delete(index);
end;
UpdateBtnStates;
end;
procedure TWLSFrm.DepOutBtnClick(Sender: TObject);
begin
if (DepVarEdit.Text <> '') then
begin
VarList.Items.Add(DepVarEdit.Text);
DepVarEdit.Text := '';
end;
UpdateBtnStates;
end;
procedure TWLSFrm.ComputeBtnClick(Sender: TObject);
VAR
i, ii, j, Noindep, DepCol, WghtCol, olddepcol, NCases, pos, col : integer;
IndepCols : IntDyneVec;
RowLabels : StrDyneVec;
X, Y : double;
Means, Variances, StdDevs, BWeights : DblDyneVec;
BetaWeights, BStdErrs, Bttests, tprobs : DblDyneVec;
PrintDesc : boolean;
Xpoints, Ypoints, UpConf, lowConf : DblDyneVec;
Xmax, Xmin, Ymax, Ymin, Xmean, Ymean, Xvariance, Yvariance, R : double;
temp, SEPred, Slope, Intercept, DF, SSx, t, ConfBand, sedata : double;
Xstddev, Ystddev, predicted : double;
ColNoSelected : IntDyneVec;
XLabel, YLabel : string;
N, Xcol, Ycol, NoSelected : integer;
lReport: TStrings;
StdErrEst: Double = 0.0;
R2: Double = 0.0;
errorcode: Boolean = false;
begin
PrintDesc := true;
SetLength(Means, NoVariables + 2);
SetLength(Variances, NoVariables + 2);
SetLength(StdDevs, NoVariables + 2);
SetLength(BWeights, NoVariables + 2);
SetLength(BetaWeights, NoVariables + 2);
SetLength(BStdErrs, NoVariables + 2);
SetLength(Bttests, NoVariables + 2);
SetLength(tprobs, NoVariables + 2);
SetLength(RowLabels, NoVariables + 2);
SetLength(IndepCols, NoVariables + 2);
SetLength(Xpoints, NoCases + 1);
SetLength(Ypoints, NoCases + 1);
SetLength(UpConf, NoCases + 1);
SetLength(lowConf, NoCases + 1);
SetLength(ColNoSelected, 2);
lReport := TStringList.Create;
try
NCases := NoCases;
Noindep := IndVarList.Items.Count;
if (Noindep = 0) then
begin
MessageDlg('No independent variables selected.', mtError, [mbOK], 0);
exit;
end;
DepCol := 0;
WghtCol := 0;
for i := 0 to NoVariables - 1 do
begin
if (OS3MainFrm.DataGrid.Cells[i+1,0] = DepVarEdit.Text) then DepCol := i+1;
if (OS3MainFrm.DataGrid.Cells[i+1,0] = WghtVarEdit.Text) then WghtCol := i+1;
for j := 0 to Noindep - 1 do
begin
if (OS3MainFrm.DataGrid.Cells[i+1,0] = IndVarList.Items.Strings[j]) then
begin
IndepCols[j] := i+1;
RowLabels[j] := IndVarList.Items.Strings[j];
end;
end; // next j
end; // next i
if (DepCol = 0) then
begin
MessageDlg('No dependent variable selected.', mtError, [mbOK], 0);
exit;
end;
// check variable types
if not ValidValue(DepCol,0) then
begin
MessageDlg('Incorrect dependent variable type.', mtError, [mbOK], 0);
exit;
end;
if (WghtCol > 0) then
begin
if not ValidValue(WghtCol,0) then
begin
MessageDlg('Incorrect weight variable type.', mtError, [mbOK], 0);
exit;
end;
end;
for j := 0 to Noindep - 1 do
begin
if not ValidValue(IndepCols[j],0) then
begin
MessageDlg('Incorrect dependent variable type.', mtError, [mbOK], 0);
exit;
end;
end;
IndepCols[NoIndep] := DepCol;
olddepcol := DepCol; // save dependent column so we can reuse DepCol
// Get OLS regression
if OLSChk.Checked then
begin
lReport.Add('OLS REGRESSION RESULTS');
MReg(Noindep, IndepCols, DepCol, RowLabels, Means, Variances, StdDevs,
BWeights, BetaWeights, BStdErrs, Bttests, tprobs, R2, stderrest,
NCases, errorcode, PrintDesc, lReport);
// Get predicted z score, residual z score, predicted raw score,
// residual raw score and squared raw residual score. Place in the DataGrid
PredictIt(IndepCols, Noindep+1, Means, StdDevs, BetaWeights, stderrest, Noindep);
lReport.Add('');
lReport.Add('==================================================================================');
lReport.Add('');
end;
if RegResChk.Checked and OLSChk.Checked then
begin
// Regress the squared residuals on the predictors
DepCol := NoVariables;
lReport.Add('REGRESSION OF SQUARED RESIDUALS ON INDEPENDENT VARIABLES');
MReg(Noindep, IndepCols, DepCol, RowLabels, Means, Variances, StdDevs,
BWeights, BetaWeights, BStdErrs, Bttests, tprobs, R2, stderrest,
NCases, errorcode, PrintDesc, lReport);
DisplayReport(lReport);
lReport.Clear;
// lReport.Add('');
// lReport.Add('==================================================================================');
// lReport.Add('');
end;
if WeightChk.Checked and RegResChk.Checked then
begin
// Get predicted squared residuals and save recipricols as weights
col := NoVariables + 1;
OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables);
DictionaryFrm.NewVar(col);
DictionaryFrm.DictGrid.Cells[1,col] := 'PredResid2';
OS3MainFrm.DataGrid.Cells[col,0] := 'PredResid2';
col := NoVariables + 1;
OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables);
DictionaryFrm.NewVar(col);
DictionaryFrm.DictGrid.Cells[1,col] := 'WEIGHT';
OS3MainFrm.DataGrid.Cells[col,0] := 'WEIGHT';
OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables);
for i := 1 to NoCases do
begin
if (ValidValue(i,col-2)) then // do we have a valid squared OLS residual?
begin
predicted := 0.0;
for j := 0 to Noindep - 1 do
begin
pos := IndepCols[j];
X := StrToFloat(OS3MainFrm.DataGrid.Cells[pos,i]);
predicted := predicted + BWeights[j] * X;
end;
predicted := predicted + BWeights[Noindep];
predicted := abs(predicted);
OS3MainFrm.DataGrid.Cells[col-1,i] := Format('%8.3f', [predicted]);
if (predicted > 0.0) then
predicted := 1.0 / sqrt(predicted)
else
predicted := 0.0;
OS3MainFrm.DataGrid.Cells[col,i] := Format('%8.3f', [predicted]);
end; // if valid case
end; // next i
end; // if regresChk
// Now, plot squared residuals against each independent variable
if PlotChk.Checked and RegResChk.Checked then
begin
Xcol := DepCol;
for ii := 0 to NoIndep - 1 do
begin
Ycol := IndepCols[ii];
N := 0;
ColNoSelected[0] := Xcol;
ColNoSelected[1] := Ycol;
NoSelected := 2;
XLabel := OS3MainFrm.DataGrid.Cells[Xcol,0];
YLabel := OS3MainFrm.DataGrid.Cells[Ycol,0];
Xmax := -1.0e308;
Xmin := 1.0e308;
Ymax := -1.0e308;
Ymin := 1.0e308;
Xmean := 0.0;
Ymean := 0.0;
Xvariance := 0.0;
Yvariance := 0.0;
R := 0.0;
for i := 1 to NoCases do
begin
if (not GoodRecord(i,NoSelected,ColNoSelected)) then continue;
N := N + 1;
X := StrToFloat(OS3MainFrm.DataGrid.Cells[Xcol,i]);
Y := StrToFloat(OS3MainFrm.DataGrid.Cells[Ycol,i]);
Xpoints[N] := X;
Ypoints[N] := Y;
if (X > Xmax) then Xmax := X;
if (X < Xmin) then Xmin := X;
if (Y > Ymax) then Ymax := Y;
if (Y < Ymin) then Ymin := Y;
Xmean := Xmean + X;
Ymean := Ymean + Y;
Xvariance := Xvariance + X * X;
Yvariance := Yvariance + Y * Y;
R := R + X * Y;
end;
// sort on X
for i := 1 to N - 1 do
begin
for j := i + 1 to N do
begin
if (Xpoints[i] > Xpoints[j]) then //swap
begin
temp := Xpoints[i];
Xpoints[i] := Xpoints[j];
Xpoints[j] := temp;
temp := Ypoints[i];
Ypoints[i] := Ypoints[j];
Ypoints[j] := temp;
end;
end;
end;
// calculate statistics
Xvariance := Xvariance - Xmean * Xmean / N;
SSx := Xvariance;
Xvariance := Xvariance / (N - 1);
Xstddev := sqrt(Xvariance);
Yvariance := Yvariance - Ymean * Ymean / N;
Yvariance := Yvariance / (N - 1);
Ystddev := sqrt(Yvariance);
R := R - Xmean * Ymean / N;
R := R / (N - 1);
R := R / (Xstddev * Ystddev);
SEPred := sqrt(1.0 - R * R) * Ystddev;
SEPred := SEPred * sqrt((N - 1) / (N - 2));
Xmean := Xmean / N;
Ymean := Ymean / N;
Slope := R * Ystddev / Xstddev;
Intercept := Ymean - Slope * Xmean;
// Now, print the descriptive statistics if requested
lReport.Add('X versus Y Plot');
lReport.Add('');
lReport.Add('X = %s, Y = %s from file %s', [
OS3MainFrm.DataGrid.Cells[Xcol,0],
OS3MainFrm.DataGrid.Cells[Ycol,0],
OS3MainFrm.FileNameEdit.Text
]);
lReport.Add('');
lReport.Add('Variable Mean Variance Std.Dev.');
lReport.Add('%-10s%8.2f %8.2f %8.2f', [OS3MainFrm.DataGrid.Cells[Xcol,0], Xmean, Xvariance, Xstddev]);
lReport.Add('%-10s%8.2f %8.2f %8.2f', [OS3MainFrm.DataGrid.Cells[Ycol,0], Ymean, Yvariance, Ystddev]);
lReport.Add('');
lReport.Add('Correlation: %8.4f', [R]);
lReport.Add('Slope: %8.2f', [Slope]);
lReport.Add('Intercept: %8.2f', [Intercept]);
lReport.Add('Standard Error of Estimate: %8.2f', [SEPred]);
lReport.Add('Number of good cases: %8d', [N]);
DisplayReport(lReport);
lReport.Clear;
// lReport.Add('');
// lReport.Add('==================================================================================');
// lReport.Add('');
// get upper and lower confidence points for each X value
ConfBand := 0.95;
DF := N - 2;
t := inverset(ConfBand,DF);
for i := 1 to N do
begin
X := Xpoints[i];
predicted := Slope * X + Intercept;
sedata := SEPred * sqrt(1.0 + (1.0 / N) + ((X - Xmean) * (X - Xmean) / SSx));
UpConf[i] := predicted + (t * sedata);
lowConf[i] := predicted - (t * sedata);
if (UpConf[i] > Ymax) then Ymax := UpConf[i];
if (lowConf[i] < Ymin) then Ymin := lowConf[i];
end;
// plot the values (and optional line and confidence band if elected)
PlotXY(Xpoints, Ypoints, UpConf, lowConf, ConfBand, Xmean, Ymean, R,
Slope, Intercept, Xmax, Xmin, Ymax, Ymin, N, XLabel, YLabel);
BlankFrm.ShowModal;
end;
end;
if UserWghtsChk.Checked then
begin
// Weight variables and do OLS regression on weighted variables
DepCol := olddepcol;
IndepCols[Noindep] := DepCol;
for i := 1 to NoCases do
begin
Y := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[NoVariables,i])); // weight
for j := 0 to Noindep do
begin
pos := IndepCols[j];
X := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[pos,i]));
X := X * Y;
OS3MainFrm.DataGrid.Cells[pos,i] := FloatToStr(X);
end;
end;
// get means of variables and subtract from the values
if OriginChk.Checked then
begin
for j := 0 to Noindep do
begin
Means[j] := 0.0;
NCases := 0;
pos := IndepCols[j];
for i := 1 to NoCases do
begin
if (ValidValue(i,pos)) then
begin
Means[j] := Means[j] + StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[pos,i]));
NCases := NCases + 1;
end;
end;
Means[j] := Means[j] / NCases;
for i := 1 to NoCases do
begin
if (ValidValue(i,pos)) then
begin
X := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[pos,i]));
X := X - Means[j];
OS3MainFrm.DataGrid.Cells[pos,i] := FloatToStr(X);
end;
end; // next i
end; // next j
end; // if origin checked
lReport.Add('WLS REGRESSION RESULTS');
MReg(Noindep, IndepCols, DepCol, RowLabels, Means, Variances, StdDevs,
BWeights, BetaWeights, BStdErrs, Bttests, tprobs, R2, stderrest,
NCases, errorcode, PrintDesc, lReport);
DisplayReport(lReport);
end // if useweightschk checked
else
// use the weights entered by the user
if (UserWghtsChk.Checked) then
begin
// Weight variables and do OLS regression on weighted variables
DepCol := olddepcol;
IndepCols[Noindep] := DepCol;
for i := 1 to NoCases do
begin
Y := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[WghtCol,i])); // weight
for j := 0 to Noindep do
begin
pos := IndepCols[j];
X := StrToFloat(OS3MainFrm.DataGrid.Cells[pos,i]);
X := X * Y;
OS3MainFrm.DataGrid.Cells[pos,i] := FloatToStr(X);
end;
end;
if (OriginChk.Checked) then // get means of variables and subtract from the values
begin
for j := 0 to Noindep do
begin
Means[j] := 0.0;
NCases := 0;
pos := IndepCols[j];
for i := 1 to NoCases do
begin
if (ValidValue(i,pos)) then
begin
Means[j] := Means[j] + StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[pos,i]));
NCases := NCases + 1;
end;
end;
Means[j] := Means[j] / NCases;
for i := 1 to NoCases do
begin
if (ValidValue(i,pos)) then
begin
X := StrToFloat(OS3MainFrm.DataGrid.Cells[pos,i]);
X := X - Means[j];
OS3MainFrm.DataGrid.Cells[pos,i] := FloatToStr(X);
end;
end; // next i
end; // next j
end; // if origin checked
lReport.Add('WLS REGRESSION RESULTS');
MReg(Noindep, IndepCols, DepCol, RowLabels, Means, Variances, StdDevs,
BWeights, BetaWeights, BStdErrs, Bttests, tprobs, R2, stderrest,
NCases, errorcode, PrintDesc, lReport);
DisplayReport(lReport);
end;
finally
lReport.Free;
IndepCols := nil;
RowLabels := nil;
tprobs := nil;
Bttests := nil;
BStdErrs := nil;
BetaWeights := nil;
BWeights := nil;
StdDevs := nil;
Variances := nil;
Means := nil;
ColNoSelected := nil;
lowConf := nil;
UpConf := nil;
Ypoints := nil;
Xpoints := nil;
// reset the variables for possible second step of WLS
//ResetBtnClick(self);
end;
end;
procedure TWLSFrm.PredictIt(ColNoSelected: IntDyneVec; NoVars: integer;
Means, StdDevs, BetaWeights: DblDyneVec;
StdErrEst: double; NoIndepVars: integer);
VAR
col, i, j, k, Index: integer;
predicted, zpredicted, z1, z2, resid, residsqr : double;
begin
// routine obtains predicted raw and standardized scores and their
// residuals. It is assumed that the dependent variable is last in the
// list of variable column pointers stored in the ColNoSelected vector.
// Get the z predicted score and its residual
col := NoVariables + 1;
// NoVariables := col;
OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables);
DictionaryFrm.DictGrid.ColCount := 8;
DictionaryFrm.NewVar(col);
OS3MainFrm.DataGrid.Cells[col,0] := 'Pred.z';
DictionaryFrm.DictGrid.Cells[1,col] := 'Pred.z';
col := NoVariables + 1;
// NoVariables := col;
DictionaryFrm.NewVar(col);
OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables);
OS3MainFrm.DataGrid.Cells[col,0] := 'z Resid.';
DictionaryFrm.DictGrid.Cells[1,col] := 'z Resid.';
OS3MainFrm.DataGrid.ColCount := OS3MainFrm.DataGrid.ColCount + 2;
for i := 1 to NoCases do
begin
zpredicted := 0.0;
for j := 0 to NoIndepVars - 1 do
begin
k := ColNoSelected[j];
z1 := (StrToFloat(OS3MainFrm.DataGrid.Cells[k,i]) - Means[j]) / StdDevs[j];
zpredicted := zpredicted + (z1 * BetaWeights[j]);
end;
OS3MainFrm.DataGrid.Cells[col-1,i] := Format('%8.4f',[zpredicted]);
if StdDevs[NoVars-1] <> 0.0 then
begin
Index := ColNoSelected[NoVars-1];
z2 := StrToFloat(OS3MainFrm.DataGrid.Cells[Index,i]);
z2 := (z2 - Means[NoVars-1]) / StdDevs[NoVars-1]; // z score
OS3MainFrm.DataGrid.Cells[col,i] := Format('%8.4f',[z2 - zpredicted]); // z residual
end;
end;
// Get raw predicted and residuals
col := NoVariables + 1;
OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables);
DictionaryFrm.NewVar(col);
DictionaryFrm.DictGrid.Cells[1,col] := 'Pred.Raw';
OS3MainFrm.DataGrid.Cells[col,0] := 'Pred.Raw';
// calculate raw predicted scores and store in DataGrid at col
for i := 1 to NoCases do
begin // predicted raw obtained from previously predicted z score
predicted := StrToFloat(OS3MainFrm.DataGrid.Cells[col-2,i]) * StdDevs[NoVars-1] + Means[NoVars-1];
OS3MainFrm.DataGrid.Cells[col,i] := Format('%8.3f',[predicted]);
end;
// Calculate residuals of predicted raw scores end;
col := NoVariables +1;
OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables);
DictionaryFrm.NewVar(col);
DictionaryFrm.DictGrid.Cells[1,col] := 'Raw Resid.';
OS3MainFrm.DataGrid.Cells[col,0] := 'Raw Resid.';
for i := 1 to NoCases do
begin
Index := ColNoSelected[NoVars-1];
resid := StrToFloat(OS3MainFrm.DataGrid.Cells[col-1,i]) - StrToFloat(OS3MainFrm.DataGrid.Cells[Index,i]);
OS3MainFrm.DataGrid.Cells[col,i] := Format('%8.3f',[resid]);
end;
// get square of raw residuals
col := NoVariables + 1;
DictionaryFrm.NewVar(col);
OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables);
DictionaryFrm.DictGrid.Cells[1,col] := 'ResidSqr';
OS3MainFrm.DataGrid.Cells[col,0] := 'ResidSqr';
for i := 1 to NoCases do
begin
residsqr := StrToFloat(OS3MainFrm.DataGrid.Cells[col-1,i]);
residsqr := residsqr * residsqr;
OS3MainFrm.DataGrid.Cells[col,i] := Format('%8.3f',[residsqr]);
end;
end;
procedure TWLSFrm.PlotXY(Xpoints, Ypoints, UpConf, LowConf : DblDyneVec;
ConfBand, Xmean, Ymean, R, Slope, Intercept : double;
Xmax, Xmin, Ymax, Ymin : double;
N : integer; XLabel, YLabel : string);
VAR
i, xpos, ypos, hleft, hright, vtop, vbottom, imagewide : integer;
vhi, hwide, offset, strhi, imagehi : integer;
valincr, Yvalue, Xvalue, value : double;
Title, outline : string;
begin
BlankFrm.Image1.Canvas.Clear;
Title := 'X versus Y PLOT Using File: ' + OS3MainFrm.FileNameEdit.Text;
BlankFrm.Caption := Title;
imagewide := BlankFrm.Image1.Width;
imagehi := BlankFrm.Image1.Height;
BlankFrm.Image1.Canvas.Pen.Color := clBlack;
BlankFrm.Image1.Canvas.Brush.Color := clWhite;
BlankFrm.Image1.Canvas.Rectangle(0,0,imagewide,imagehi);
BlankFrm.Image1.Canvas.FloodFill(0,0,clWhite,fsBorder);
vtop := 20;
vbottom := round(imagehi) - 80;
vhi := vbottom - vtop;
hleft := 100;
hright := imagewide - 80;
hwide := hright - hleft;
BlankFrm.Image1.Canvas.Pen.Color := clBlack;
BlankFrm.Image1.Canvas.Brush.Color := clWhite;
// Draw chart border
BlankFrm.Image1.Canvas.Rectangle(0,0,imagewide,imagehi);
// draw Means
ypos := round(vhi * ( (Ymax - Ymean) / (Ymax - Ymin)));
ypos := ypos + vtop;
xpos := hleft;
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
xpos := hright;
BlankFrm.Image1.Canvas.Pen.Color := clGreen;
BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
Title := 'MEAN ';
Title := Title + YLabel;
strhi := BlankFrm.Image1.Canvas.TextHeight(Title);
ypos := ypos - strhi div 2;
BlankFrm.Image1.Canvas.Brush.Color := clWhite;
BlankFrm.Image1.Canvas.TextOut(xpos,ypos,Title);
xpos := round(hwide * ( (Xmean - Xmin) / (Xmax - Xmin)));
xpos := xpos + hleft;
ypos := vtop;
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
ypos := vbottom;
BlankFrm.Image1.Canvas.Pen.Color := clGreen;
BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
Title := 'MEAN ';
Title := Title + XLabel;
strhi := BlankFrm.Image1.Canvas.TextWidth(Title);
xpos := xpos - strhi div 2;
ypos := vtop - BlankFrm.Image1.Canvas.TextHeight(Title);
BlankFrm.Image1.Canvas.Brush.Color := clWhite;
BlankFrm.Image1.Canvas.TextOut(xpos,ypos,Title);
// draw slope line
BlankFrm.Image1.Canvas.Pen.Color := clBlack;
Yvalue := (Xpoints[1] * Slope) + Intercept; // predicted score
ypos := round(vhi * ( (Ymax - Yvalue) / (Ymax - Ymin)));
ypos := ypos + vtop;
xpos := round(hwide * ( (Xpoints[1]- Xmin) / (Xmax - Xmin)));
xpos := xpos + hleft;
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
Yvalue := (Xpoints[N] * Slope) + Intercept; // predicted score
ypos := round(vhi * ( (Ymax - Yvalue) / (Ymax - Ymin)));
ypos := ypos + vtop;
xpos := round(hwide * ( (Xpoints[N] - Xmin) / (Xmax - Xmin)));
xpos := xpos + hleft;
BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
// draw horizontal axis
BlankFrm.Image1.Canvas.Pen.Color := clBlack;
BlankFrm.Image1.Canvas.MoveTo(hleft,vbottom);
BlankFrm.Image1.Canvas.LineTo(hright,vbottom);
valincr := (Xmax - Xmin) / 10.0;
for i := 1 to 11 do
begin
ypos := vbottom;
Xvalue := Xmin + valincr * (i - 1);
xpos := round(hwide * ((Xvalue - Xmin) / (Xmax - Xmin)));
xpos := xpos + hleft;
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
ypos := ypos + 10;
BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
outline := format('%6.2f',[Xvalue]);
Title := outline;
offset := BlankFrm.Image1.Canvas.TextWidth(Title) div 2;
xpos := xpos - offset;
BlankFrm.Image1.Canvas.Pen.Color := clBlack;
BlankFrm.Image1.Canvas.TextOut(xpos,ypos,Title);
end;
xpos := hleft + (hwide div 2) - (BlankFrm.Image1.Canvas.TextWidth(XLabel) div 2);
ypos := vbottom + 20;
BlankFrm.Image1.Canvas.TextOut(xpos,ypos,XLabel);
outline := format('R(X,Y) := %5.3f, Slope := %6.2f, Intercept := %6.2f',
[R,Slope,Intercept]);
Title := outline;
xpos := hleft + (hwide div 2) - (BlankFrm.Image1.Canvas.TextWidth(Title) div 2);
ypos := ypos + 15;
BlankFrm.Image1.Canvas.TextOut(xpos,ypos,Title);
// Draw vertical axis
Title := YLabel;
// xpos := hleft - 10 - BlankFrm.Image1.Canvas.TextWidth(Title) / 2;
xpos := 10;
ypos := vtop - 8 - BlankFrm.Image1.Canvas.TextHeight(Title);
BlankFrm.Image1.Canvas.TextOut(xpos,ypos,YLabel);
xpos := hleft;
ypos := vtop;
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
ypos := vbottom;
BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
valincr := (Ymax - Ymin) / 10.0;
for i := 1 to 11 do
begin
value := Ymax - ((i-1) * valincr);
outline := format('%8.2f',[value]);
Title := outline;
strhi := BlankFrm.Image1.Canvas.TextHeight(Title);
xpos := 10;
Yvalue := Ymax - (valincr * (i-1));
ypos := round(vhi * ( (Ymax - Yvalue) / (Ymax - Ymin)));
ypos := ypos + vtop - strhi div 2;
BlankFrm.Image1.Canvas.TextOut(xpos,ypos,Title);
xpos := hleft;
ypos := ypos + strhi div 2;
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
xpos := hleft - 10;
BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
end;
// draw points for x and y pairs
for i := 1 to N do
begin
ypos := round(vhi * ( (Ymax - Ypoints[i]) / (Ymax - Ymin)));
ypos := ypos + vtop;
xpos := round(hwide * ( (Xpoints[i] - Xmin) / (Xmax - Xmin)));
xpos := xpos + hleft;
BlankFrm.Image1.Canvas.Brush.Color := clNavy;
BlankFrm.Image1.Canvas.Brush.Style := bsSolid;
BlankFrm.Image1.Canvas.Pen.Color := clNavy;
BlankFrm.Image1.Canvas.Ellipse(xpos,ypos,xpos+5,ypos+5);
end;
// draw confidence bands if requested
if not (ConfBand = 0.0) then
begin
BlankFrm.Image1.Canvas.Pen.Color := clRed;
ypos := round(vhi * ((Ymax - UpConf[1]) / (Ymax - Ymin)));
ypos := ypos + vtop;
xpos := round(hwide * ( (Xpoints[1] - Xmin) / (Xmax - Xmin)));
xpos := xpos + hleft;
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
for i := 2 to N do
begin
ypos := round(vhi * ((Ymax - UpConf[i]) / (Ymax - Ymin)));
ypos := ypos + vtop;
xpos := round(hwide * ( (Xpoints[i] - Xmin) / (Xmax - Xmin)));
xpos := xpos + hleft;
BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
end;
ypos := round(vhi * ((Ymax - LowConf[1]) / (Ymax - Ymin)));
ypos := ypos + vtop;
xpos := round(hwide * ( (Xpoints[1] - Xmin) / (Xmax - Xmin)));
xpos := xpos + hleft;
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
for i := 2 to N do
begin
ypos := round(vhi * ((Ymax - LowConf[i]) / (Ymax - Ymin)));
ypos := ypos + vtop;
xpos := round(hwide * ( (Xpoints[i] - Xmin) / (Xmax - Xmin)));
xpos := xpos + hleft;
BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
end;
end;
end;
procedure TWLSFrm.UpdateBtnStates;
var
i: Integer;
lSelected: Boolean;
begin
lSelected := false;
for i:=0 to VarList.Items.Count-1 do
if Varlist.Selected[i] then
begin
lSelected := true;
break;
end;
DepInBtn.Enabled := lSelected and (DepVarEdit.Text = '');
IndInBtn.Enabled := lSelected;
WghtInBtn.Enabled := lSelected and (WghtVarEdit.Text = '');
lSelected := false;
for i:=0 to IndVarList.Items.Count-1 do
if IndVarList.Selected[i] then
begin
lSelected := true;
break;
end;
DepOutBtn.Enabled := (DepVarEdit.Text <> '');
IndOutBtn.Enabled := lSelected;
WghtOutBtn.Enabled := (WghtVarEdit.Text <> '');
end;
initialization
{$I wlsunit.lrs}
end.