You've already forked lazarus-ccr
LazStats: Fix XBar Control Chart UCL/LCL values to agree with commercial JMP statistics software.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7664 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -11,11 +11,12 @@ object BasicSPCForm: TBasicSPCForm
|
||||
OnShow = FormShow
|
||||
LCLVersion = '2.1.0.0'
|
||||
object SpecsPanel: TPanel
|
||||
Left = 0
|
||||
Left = 8
|
||||
Height = 438
|
||||
Top = 0
|
||||
Width = 357
|
||||
Align = alLeft
|
||||
BorderSpacing.Left = 8
|
||||
BorderSpacing.Right = 3
|
||||
BevelOuter = bvNone
|
||||
ClientHeight = 438
|
||||
@ -111,11 +112,10 @@ object BasicSPCForm: TBasicSPCForm
|
||||
object VarListLabel: TLabel
|
||||
AnchorSideLeft.Control = SpecsPanel
|
||||
AnchorSideTop.Control = SpecsPanel
|
||||
Left = 8
|
||||
Left = 0
|
||||
Height = 15
|
||||
Top = 8
|
||||
Width = 97
|
||||
BorderSpacing.Left = 8
|
||||
BorderSpacing.Top = 8
|
||||
Caption = 'Selection Variables'
|
||||
ParentColor = False
|
||||
@ -126,12 +126,11 @@ object BasicSPCForm: TBasicSPCForm
|
||||
AnchorSideTop.Side = asrBottom
|
||||
AnchorSideRight.Control = MeasInBtn
|
||||
AnchorSideBottom.Control = ButtonPanel
|
||||
Left = 8
|
||||
Left = 0
|
||||
Height = 363
|
||||
Top = 25
|
||||
Width = 150
|
||||
Width = 158
|
||||
Anchors = [akTop, akLeft, akRight, akBottom]
|
||||
BorderSpacing.Left = 8
|
||||
BorderSpacing.Top = 2
|
||||
BorderSpacing.Right = 8
|
||||
BorderSpacing.Bottom = 8
|
||||
@ -266,17 +265,17 @@ object BasicSPCForm: TBasicSPCForm
|
||||
end
|
||||
end
|
||||
object SpecsSplitter: TSplitter
|
||||
Left = 360
|
||||
Left = 368
|
||||
Height = 438
|
||||
Top = 0
|
||||
Width = 5
|
||||
ResizeStyle = rsPattern
|
||||
end
|
||||
object PageControl: TPageControl
|
||||
Left = 368
|
||||
Left = 376
|
||||
Height = 426
|
||||
Top = 6
|
||||
Width = 553
|
||||
Width = 545
|
||||
ActivePage = ReportPage
|
||||
Align = alClient
|
||||
BorderSpacing.Left = 3
|
||||
@ -288,24 +287,24 @@ object BasicSPCForm: TBasicSPCForm
|
||||
object ReportPage: TTabSheet
|
||||
Caption = 'Report'
|
||||
ClientHeight = 398
|
||||
ClientWidth = 545
|
||||
ClientWidth = 537
|
||||
object Panel1: TPanel
|
||||
Left = 6
|
||||
Height = 358
|
||||
Top = 34
|
||||
Width = 533
|
||||
Width = 525
|
||||
Align = alClient
|
||||
BorderSpacing.Around = 6
|
||||
BevelOuter = bvNone
|
||||
BorderStyle = bsSingle
|
||||
ClientHeight = 354
|
||||
ClientWidth = 529
|
||||
ClientWidth = 521
|
||||
TabOrder = 0
|
||||
object ReportMemo: TMemo
|
||||
Left = 4
|
||||
Height = 346
|
||||
Top = 4
|
||||
Width = 521
|
||||
Width = 513
|
||||
Align = alClient
|
||||
BorderSpacing.Around = 4
|
||||
BorderStyle = bsNone
|
||||
@ -320,7 +319,7 @@ object BasicSPCForm: TBasicSPCForm
|
||||
Left = 0
|
||||
Height = 22
|
||||
Top = 6
|
||||
Width = 541
|
||||
Width = 533
|
||||
AutoSize = True
|
||||
BorderSpacing.Top = 6
|
||||
BorderSpacing.Right = 4
|
||||
@ -359,12 +358,12 @@ object BasicSPCForm: TBasicSPCForm
|
||||
object ChartPage: TTabSheet
|
||||
Caption = 'Chart'
|
||||
ClientHeight = 398
|
||||
ClientWidth = 545
|
||||
ClientWidth = 537
|
||||
object ChartToolBar: TToolBar
|
||||
Left = 0
|
||||
Height = 22
|
||||
Top = 6
|
||||
Width = 541
|
||||
Width = 533
|
||||
AutoSize = True
|
||||
BorderSpacing.Top = 6
|
||||
BorderSpacing.Right = 4
|
||||
|
@ -95,7 +95,7 @@ var
|
||||
|
||||
// Constants for correction of standard deviation, needed by some charts.
|
||||
const
|
||||
C4: array[1..24] of double = (
|
||||
C4: array[2..25] of double = (
|
||||
0.7979, 0.8862, 0.9213, 0.9400, 0.9515, 0.9594, 0.9650, 0.9693,
|
||||
0.9727, 0.9754, 0.9776, 0.9794, 0.9810, 0.9823, 0.9835, 0.9845, 0.9854, 0.9862,
|
||||
0.9869, 0.9876, 0.9882, 0.9887, 0.9892, 0.9896);
|
||||
@ -193,7 +193,7 @@ begin
|
||||
CloseBtn.Constraints.MinWidth := w;
|
||||
|
||||
SpecsPanel.Constraints.MinWidth := Max(
|
||||
VarListLabel.Left + VarListLabel.Width + MeasLabel.Width,
|
||||
VarListLabel.Left + VarListLabel.Width + Varlist.BorderSpacing.Right * 2 + MeasInBtn.Width + MeasLabel.Width,
|
||||
CloseBtn.Left + CloseBtn.Width - HelpBtn.Left + HelpBtn.BorderSpacing.Around
|
||||
);
|
||||
Constraints.MinHeight := MeasEdit.Top + MeasEdit.Height + MeasEdit.BorderSpacing.Bottom + ButtonPanel.Height;
|
||||
|
@ -1,82 +1,82 @@
|
||||
inherited XBarChartForm: TXBarChartForm
|
||||
Left = 572
|
||||
Height = 443
|
||||
Height = 431
|
||||
Top = 215
|
||||
HelpType = htKeyword
|
||||
HelpKeyword = 'html/XBarChart.htm'
|
||||
Caption = 'X-Bar Control Chart'
|
||||
ClientHeight = 443
|
||||
ClientHeight = 431
|
||||
OnActivate = FormActivate
|
||||
inherited SpecsPanel: TPanel
|
||||
Height = 443
|
||||
Width = 475
|
||||
ClientHeight = 443
|
||||
ClientWidth = 475
|
||||
Height = 431
|
||||
Width = 379
|
||||
ClientHeight = 431
|
||||
ClientWidth = 379
|
||||
inherited ButtonPanel: TPanel
|
||||
Top = 401
|
||||
Width = 475
|
||||
ClientWidth = 475
|
||||
Top = 389
|
||||
Width = 379
|
||||
ClientWidth = 379
|
||||
TabOrder = 5
|
||||
inherited CloseBtn: TButton
|
||||
Left = 420
|
||||
Left = 324
|
||||
end
|
||||
inherited ComputeBtn: TButton
|
||||
Left = 336
|
||||
Left = 240
|
||||
end
|
||||
inherited ResetBtn: TButton
|
||||
Left = 274
|
||||
Left = 178
|
||||
end
|
||||
inherited HelpBtn: TButton
|
||||
Left = 223
|
||||
Left = 127
|
||||
end
|
||||
inherited Bevel1: TBevel
|
||||
Width = 467
|
||||
Width = 371
|
||||
end
|
||||
end
|
||||
inherited VarList: TListBox
|
||||
Height = 368
|
||||
Width = 209
|
||||
Height = 356
|
||||
Width = 169
|
||||
end
|
||||
inherited GroupLabel: TLabel
|
||||
Left = 257
|
||||
Left = 209
|
||||
end
|
||||
inherited GroupEdit: TEdit
|
||||
Left = 257
|
||||
Width = 218
|
||||
Left = 209
|
||||
Width = 170
|
||||
end
|
||||
inherited MeasLabel: TLabel
|
||||
Left = 257
|
||||
Left = 209
|
||||
end
|
||||
inherited MeasEdit: TEdit
|
||||
AnchorSideRight.Control = LevelOptns
|
||||
Left = 257
|
||||
Width = 218
|
||||
Left = 209
|
||||
Width = 170
|
||||
end
|
||||
inherited Bevel2: TBevel
|
||||
Left = 226
|
||||
Left = 178
|
||||
end
|
||||
inherited MeasInBtn: TSpeedButton
|
||||
Left = 225
|
||||
Left = 177
|
||||
end
|
||||
inherited MeasOutBtn: TSpeedButton
|
||||
Left = 226
|
||||
Left = 178
|
||||
end
|
||||
inherited GroupInBtn: TSpeedButton
|
||||
Left = 225
|
||||
Left = 177
|
||||
end
|
||||
inherited GroupOutBtn: TSpeedButton
|
||||
Left = 226
|
||||
Left = 178
|
||||
end
|
||||
object SigmaOpts: TRadioGroup[12]
|
||||
AnchorSideLeft.Control = MeasEdit
|
||||
AnchorSideTop.Control = GroupEdit
|
||||
AnchorSideLeft.Control = MeasInBtn
|
||||
AnchorSideTop.Control = GroupOutBtn
|
||||
AnchorSideTop.Side = asrBottom
|
||||
AnchorSideRight.Control = LevelOptns
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 257
|
||||
Left = 177
|
||||
Height = 128
|
||||
Top = 145
|
||||
Width = 218
|
||||
Top = 153
|
||||
Width = 202
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
AutoFill = True
|
||||
BorderSpacing.Top = 12
|
||||
@ -90,7 +90,7 @@ inherited XBarChartForm: TXBarChartForm
|
||||
ChildSizing.Layout = cclLeftToRightThenTopToBottom
|
||||
ChildSizing.ControlsPerLine = 1
|
||||
ClientHeight = 108
|
||||
ClientWidth = 214
|
||||
ClientWidth = 198
|
||||
ItemIndex = 0
|
||||
Items.Strings = (
|
||||
'3 Sigma'
|
||||
@ -106,7 +106,7 @@ inherited XBarChartForm: TXBarChartForm
|
||||
Left = 128
|
||||
Height = 23
|
||||
Top = 80
|
||||
Width = 74
|
||||
Width = 58
|
||||
Alignment = taRightJustify
|
||||
Anchors = [akLeft, akRight, akBottom]
|
||||
BorderSpacing.Right = 8
|
||||
@ -115,22 +115,22 @@ inherited XBarChartForm: TXBarChartForm
|
||||
end
|
||||
end
|
||||
object LevelOptns: TGroupBox[13]
|
||||
AnchorSideLeft.Control = MeasEdit
|
||||
AnchorSideLeft.Control = MeasInBtn
|
||||
AnchorSideTop.Control = SigmaOpts
|
||||
AnchorSideTop.Side = asrBottom
|
||||
AnchorSideRight.Control = MeasEdit
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 257
|
||||
Left = 177
|
||||
Height = 103
|
||||
Top = 285
|
||||
Width = 218
|
||||
Top = 293
|
||||
Width = 202
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
AutoSize = True
|
||||
BorderSpacing.Top = 12
|
||||
BorderSpacing.Bottom = 8
|
||||
Caption = 'Show...'
|
||||
ClientHeight = 83
|
||||
ClientWidth = 214
|
||||
ClientWidth = 198
|
||||
TabOrder = 4
|
||||
object UpperSpecChk: TCheckBox
|
||||
AnchorSideLeft.Control = LevelOptns
|
||||
@ -221,28 +221,28 @@ inherited XBarChartForm: TXBarChartForm
|
||||
end
|
||||
end
|
||||
inherited SpecsSplitter: TSplitter
|
||||
Left = 478
|
||||
Height = 443
|
||||
Left = 390
|
||||
Height = 431
|
||||
end
|
||||
inherited PageControl: TPageControl
|
||||
Left = 486
|
||||
Height = 431
|
||||
Width = 435
|
||||
Left = 398
|
||||
Height = 419
|
||||
Width = 523
|
||||
inherited ReportPage: TTabSheet
|
||||
ClientHeight = 403
|
||||
ClientWidth = 427
|
||||
ClientHeight = 391
|
||||
ClientWidth = 515
|
||||
inherited Panel1: TPanel
|
||||
Height = 363
|
||||
Width = 415
|
||||
ClientHeight = 359
|
||||
ClientWidth = 411
|
||||
inherited ReportMemo: TMemo
|
||||
Height = 351
|
||||
Width = 403
|
||||
Width = 503
|
||||
ClientHeight = 347
|
||||
ClientWidth = 499
|
||||
inherited ReportMemo: TMemo
|
||||
Height = 339
|
||||
Width = 491
|
||||
end
|
||||
end
|
||||
inherited ReportToolBar: TToolBar
|
||||
Width = 423
|
||||
Width = 511
|
||||
end
|
||||
end
|
||||
inherited ChartPage: TTabSheet
|
||||
|
@ -59,12 +59,15 @@ begin
|
||||
VarList.Constraints.MinWidth := VarListLabel.Width;
|
||||
SpecsPanel.Constraints.MinWidth := Max(
|
||||
CloseBtn.Left + CloseBtn.Width - HelpBtn.Left + HelpBtn.BorderSpacing.Around,
|
||||
LevelOptns.Width * 2 + VarList.BorderSpacing.Right + VarList.BorderSpacing.Left
|
||||
LevelOptns.Width * 2 + VarList.BorderSpacing.Right //* 2 + MeasInBtn.Width
|
||||
);
|
||||
Constraints.MinHeight := LevelOptns.Top + LevelOptns.Height + LevelOptns.BorderSpacing.Bottom + ButtonPanel.Height;
|
||||
|
||||
LevelOptns.AnchorSideRight.Control := MeasEdit;
|
||||
LevelOptns.AnchorSideRight.Side := asrBottom;
|
||||
|
||||
if Height < Constraints.MinHeight then
|
||||
Height := 1; // enforce height autosizing
|
||||
finally
|
||||
EnableAutoSizing;
|
||||
end;
|
||||
@ -74,7 +77,6 @@ end;
|
||||
procedure TXBarChartForm.Compute;
|
||||
var
|
||||
i, j: Integer;
|
||||
sigma: Double;
|
||||
upperSpec: Double = NaN;
|
||||
lowerSpec: Double = NaN;
|
||||
targetSpec: Double = NaN;
|
||||
@ -83,12 +85,10 @@ var
|
||||
means: DblDyneVec = nil;
|
||||
stdDev: DblDyneVec = nil;
|
||||
count: IntDyneVec = nil;
|
||||
numGrps: Integer;
|
||||
numGrps, grpIndex, totalNumCases, grpSize: Integer;
|
||||
grp: String;
|
||||
grpIndex: Integer;
|
||||
totalNumCases: Integer;
|
||||
X, Xsq: Double;
|
||||
UCL, LCL, grandMean, grandSD, stdErrMean, C4Value: Double;
|
||||
sigma, aveStdDev, UCL, LCL, grandMean, grandSD, SEMean, C4Value: Double;
|
||||
lReport: TStrings;
|
||||
begin
|
||||
if GroupEdit.Text <> '' then
|
||||
@ -126,11 +126,11 @@ begin
|
||||
SetLength(means, numGrps);
|
||||
SetLength(count, numGrps);
|
||||
SetLength(stddev, numGrps);
|
||||
stdErrMean := 0.0;
|
||||
SEMean := 0.0;
|
||||
grandMean := 0.0;
|
||||
totalNumCases := 0;
|
||||
|
||||
// calculate group means, grand mean, group sd's, semeans
|
||||
// calculate group means, grand mean, group sd's, seMean
|
||||
for i := 1 to NoCases do
|
||||
begin
|
||||
if not GoodRecord(i, Length(ColNoSelected), ColNoSelected) then continue;
|
||||
@ -151,30 +151,48 @@ begin
|
||||
means[grpIndex] := means[grpIndex] + X;
|
||||
stddev[grpIndex] := stddev[grpIndex] + Xsq;
|
||||
grandMean := grandMean + X;
|
||||
stdErrMean := stdErrMean + Xsq;
|
||||
SEMean := SEMean + Xsq;
|
||||
inc(totalNumCases);
|
||||
end;
|
||||
|
||||
stdErrMean := stdErrMean - sqr(grandMean) / totalNumCases;
|
||||
stdErrMean := sqrt(stderrMean / (totalNumCases - 1));
|
||||
grandSD := stdErrMean;
|
||||
stdErrMean := stdErrMean / sqrt(totalNumCases);
|
||||
SEMean := SEMean - sqr(grandMean) / totalNumCases;
|
||||
SEMean := sqrt(SEMean / (totalNumCases - 1));
|
||||
grandSD := SEMean;
|
||||
SEMean := SEMean / sqrt(totalNumCases);
|
||||
grandMean := grandMean / totalNumCases;
|
||||
|
||||
if (GroupEdit.Text = '') then
|
||||
begin
|
||||
// Individuals chart
|
||||
grpSize := 1;
|
||||
SetLength(means, totalNumCases);
|
||||
SetLength(stddev, totalNumCases);
|
||||
Setlength(count, totalNumCases);
|
||||
for i := 0 to totalNumCases-1 do
|
||||
stddev[i] := stdErrMean;
|
||||
C4Value := 1.0 / C4[totalNumCases-1];
|
||||
UCL := grandMean + sigma * stdErrMean * C4Value;
|
||||
LCL := grandMean - sigma * stdErrMean * C4Value;
|
||||
stddev[i] := SEMean;
|
||||
aveStdDev := NaN;
|
||||
if totalNumCases <= 25 then
|
||||
C4Value := C4[totalNumCases]
|
||||
else
|
||||
C4Value := 1.0;
|
||||
UCL := grandMean + sigma * grandSD / C4Value;
|
||||
LCL := grandMean - sigma * grandSD / C4Value;
|
||||
end else
|
||||
begin
|
||||
// Grouped chart
|
||||
|
||||
// Check group size - it is assumed that all groups are equally sized
|
||||
grpSize := count[0];
|
||||
for i := 1 to numGrps-1 do
|
||||
if count[i] <> grpSize then
|
||||
begin
|
||||
ErrorMsg('All groups must have the same size.');
|
||||
exit;
|
||||
end;
|
||||
|
||||
aveStdDev := aveStdDev + stdDev[i];
|
||||
|
||||
aveStdDev := 0;
|
||||
for i := 0 to numGrps-1 do
|
||||
begin
|
||||
if count[i] = 0 then
|
||||
@ -188,14 +206,18 @@ begin
|
||||
else
|
||||
begin
|
||||
stddev[i] := stddev[i] - sqr(means[i]) / count[i];
|
||||
stddev[i] := stddev[i] / (count[i] - 1);
|
||||
stddev[i] := sqrt(stddev[i]);
|
||||
stddev[i] := stddev[i] / (count[i] - 1); // Variance of group i
|
||||
aveStdDev := aveStdDev + stdDev[i]; // Sum of variances
|
||||
stddev[i] := sqrt(stddev[i]); // StdDev of group i
|
||||
end;
|
||||
means[i] := means[i] / count[i];
|
||||
end;
|
||||
end;
|
||||
UCL := grandMean + sigma * stdErrMean;
|
||||
LCL := grandMean - sigma * stdErrMean;
|
||||
aveStdDev := sqrt(aveStdDev / (numGrps * grpSize));
|
||||
UCL := grandMean + sigma * aveStdDev;
|
||||
LCL := grandMean - sigma * aveStdDev;
|
||||
// UCL := grandMean + sigma * SEMean; // old LazStats calculation -- does not agree with JMP software.
|
||||
// LCL := grandMean - sigma * SEMean;
|
||||
end;
|
||||
|
||||
// Print results
|
||||
@ -203,11 +225,14 @@ begin
|
||||
try
|
||||
lReport.Add('X BAR CHART RESULTS');
|
||||
lReport.Add('');
|
||||
lReport.Add('Number of samples: %8d', [totalNumCases]);
|
||||
lReport.Add('Number of values: %8d', [totalNumCases]);
|
||||
lReport.Add('Number of groups: %8d', [numGrps]);
|
||||
lReport.Add('Group size: %8d', [grpSize]);
|
||||
lReport.Add('');
|
||||
lReport.Add('Grand Mean: %8.3f', [grandMean]);
|
||||
lReport.Add('Standard Deviation: %8.3f', [grandSD]);
|
||||
lReport.Add('Standard Error of Mean: %8.3f', [stdErrMean]);
|
||||
lReport.Add('');
|
||||
lReport.Add('Standard Error of Mean: %8.3f', [SEMean]);
|
||||
lReport.Add('Average Std Deviation: %8.3f', [aveStdDev]);
|
||||
lReport.Add('Lower Control Limit: %8.3f', [LCL]);
|
||||
lReport.Add('Upper Control Limit: %8.3f', [UCL]);
|
||||
lReport.Add('');
|
||||
|
@ -24,6 +24,8 @@ object ChartFrame: TChartFrame
|
||||
end
|
||||
item
|
||||
Grid.Color = clSilver
|
||||
Intervals.MaxLength = 80
|
||||
Intervals.MinLength = 30
|
||||
Alignment = calBottom
|
||||
Marks.LabelBrush.Style = bsClear
|
||||
Minors = <>
|
||||
|
Reference in New Issue
Block a user