LazStats: Refactor ResistanceLineUnit, use report-and-chart template form.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7755 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2020-10-09 21:35:35 +00:00
parent 5c7f373489
commit ae55a077f0
10 changed files with 1068 additions and 1181 deletions

View File

@ -64,3 +64,4 @@ correlation, means, standard deviations and confidence interval for each correla
160=Correspondence analysis is a method for examining the relationship between two sets of categorical variables much as in a Chi-Squared analysis of a two-way contingency table. In fact, a typical chi-squared analysis is completed as part of this procedure. In addition, visualization of the relationships among the columns or rows of the analysis is performed in a manner similar to factor analysis. The data analyzed in the visualization is the table of relative proportions, that is, the original frequency values divided by the sum of all frequencies. The relative proportions of the row sums and the column sums are termed the �masses� of the rows or columns. The method used to analyze the relative proportions involves what is now called the �Generalized Singular Value Decomposition� or more simply the generalized SVD. This method obtains roots and vectors of a rectangular matrix by decomposing that matrix into three portions: a matrix of left singular column vectors (A) that has n rows and q columns (n � q), a square diagonal matrix with q rows and columns of singular values (D), and a transposed matrix (B�) that is m x q in size of right generalized singular vectors (m = q-1). Completing this analysis involves several steps. The first is to obtain the (regular) SVD analysis of a matrix Q defined as Dr-1/2PDc -1/2 where Dr and Dc are diagonal matrices of row and column relative proportions and P is the matrix of relative proportions. The SVD of Q gives Q = U D V� where D is the desired diagonal matrix of eigenvalues and U�U = V�V = I. It should be noted that the first of the q roots is trivial and to be ignored. At this point we obtain A = Dr1/2U and B = Dc 1/2 V. The results of this SVD analysis is available on the output. Now P = ADB�. The row coordinates F and column coordinates G are then computed according to the table: Analysis Choice Button Selected Row Coordinates Column Coordinates Row Profile Row F = Dr-1AD G = Dc-1B Column Profile Column F = Dr-1A G = Dc-1BD Both Profiles Both F = Dr-1AD G = Dc-1BD If Row profiles are computed, the row coordinates are weighted centroids of the column coordinates and the inertias D2 refer only to the row points. If the column profiles are computed, the column coordinates are weighted eentroids of the row coordinates and the inertias D2 refer only to the column points. If both profiles are selected, neither row or column coordinates are weighted centroids of the other but the inertias D2 refer to both sets of points. The q-1 inertias are plotted in a manner similar to a scree plot of roots in a factor analysis. The total inertia is, in fact, the chi-squared statistic divided by the total of all cell frequencies. You may elect to plot the coordinates for any two pairs of coordinates. This will provide a graphical representation of the separation of the row or column categories similar to a plot of variables in a discriminant function analysis or factors in a factor analysis. A way of looking at correspondence analysis is to consider it as a method for decomposing the overall inertia by identifying a small number of dimensions in which the deviations from the expected values can be represented. This is similar to factor analysis where the total variance is decomposed so as to arrive at a lower dimensional representation of variables. 160=Correspondence analysis is a method for examining the relationship between two sets of categorical variables much as in a Chi-Squared analysis of a two-way contingency table. In fact, a typical chi-squared analysis is completed as part of this procedure. In addition, visualization of the relationships among the columns or rows of the analysis is performed in a manner similar to factor analysis. The data analyzed in the visualization is the table of relative proportions, that is, the original frequency values divided by the sum of all frequencies. The relative proportions of the row sums and the column sums are termed the �masses� of the rows or columns. The method used to analyze the relative proportions involves what is now called the �Generalized Singular Value Decomposition� or more simply the generalized SVD. This method obtains roots and vectors of a rectangular matrix by decomposing that matrix into three portions: a matrix of left singular column vectors (A) that has n rows and q columns (n � q), a square diagonal matrix with q rows and columns of singular values (D), and a transposed matrix (B�) that is m x q in size of right generalized singular vectors (m = q-1). Completing this analysis involves several steps. The first is to obtain the (regular) SVD analysis of a matrix Q defined as Dr-1/2PDc -1/2 where Dr and Dc are diagonal matrices of row and column relative proportions and P is the matrix of relative proportions. The SVD of Q gives Q = U D V� where D is the desired diagonal matrix of eigenvalues and U�U = V�V = I. It should be noted that the first of the q roots is trivial and to be ignored. At this point we obtain A = Dr1/2U and B = Dc 1/2 V. The results of this SVD analysis is available on the output. Now P = ADB�. The row coordinates F and column coordinates G are then computed according to the table: Analysis Choice Button Selected Row Coordinates Column Coordinates Row Profile Row F = Dr-1AD G = Dc-1B Column Profile Column F = Dr-1A G = Dc-1BD Both Profiles Both F = Dr-1AD G = Dc-1BD If Row profiles are computed, the row coordinates are weighted centroids of the column coordinates and the inertias D2 refer only to the row points. If the column profiles are computed, the column coordinates are weighted eentroids of the row coordinates and the inertias D2 refer only to the column points. If both profiles are selected, neither row or column coordinates are weighted centroids of the other but the inertias D2 refer to both sets of points. The q-1 inertias are plotted in a manner similar to a scree plot of roots in a factor analysis. The total inertia is, in fact, the chi-squared statistic divided by the total of all cell frequencies. You may elect to plot the coordinates for any two pairs of coordinates. This will provide a graphical representation of the separation of the row or column categories similar to a plot of variables in a discriminant function analysis or factors in a factor analysis. A way of looking at correspondence analysis is to consider it as a method for decomposing the overall inertia by identifying a small number of dimensions in which the deviations from the expected values can be represented. This is similar to factor analysis where the total variance is decomposed so as to arrive at a lower dimensional representation of variables.
161=Directions:\n(1) Select the X variable common to all of the Y variables to be selected.\n(2) Select the Y variables.\n(3) Enter a label for the plot.\n(4) Select the options desired.\n(5) Click the Compute button to obtain results. 161=Directions:\n(1) Select the X variable common to all of the Y variables to be selected.\n(2) Select the Y variables.\n(3) Enter a label for the plot.\n(4) Select the options desired.\n(5) Click the Compute button to obtain results.
162=This procedure plots the frequency of cases in each of the groups in a group variable. The group variable should be defined as an integer variable.\n\nSelect the variable and type of plot and click the Compute button for the results. 162=This procedure plots the frequency of cases in each of the groups in a group variable. The group variable should be defined as an integer variable.\n\nSelect the variable and type of plot and click the Compute button for the results.
163=The Resistant Line procedure creates three equal groups by sorting on the X variable and obtaining the median value of each group.\nThe median values for these three groups on both the X and Y variables are then plotted. The line from the low group median to the middle group median is plotted as well as the line from the middle group to the top group median. A comparison of the slope of these two lines gives an indication of the degree to which the data fit a straight line. Enter the X and Y variables to be analyzed and click the compute button.

View File

@ -126,6 +126,8 @@ begin
Grid.Color := clSilver; Grid.Color := clSilver;
Grid.Style := psSolid; Grid.Style := psSolid;
end; end;
PageControl.ActivePage := ChartPage;
end; end;

View File

@ -19,17 +19,17 @@ inherited PlotXYFrm: TPlotXYFrm
TabOrder = 11 TabOrder = 11
end end
inherited ComputeBtn: TButton inherited ComputeBtn: TButton
Left = 238 Left = 237
Top = 459 Top = 459
TabOrder = 10 TabOrder = 10
end end
inherited ResetBtn: TButton inherited ResetBtn: TButton
Left = 176 Left = 175
Top = 459 Top = 459
TabOrder = 9 TabOrder = 9
end end
inherited HelpBtn: TButton inherited HelpBtn: TButton
Left = 117 Left = 116
Top = 459 Top = 459
TabOrder = 8 TabOrder = 8
end end

View File

@ -39,18 +39,19 @@ type
procedure XOutBtnClick(Sender: TObject); procedure XOutBtnClick(Sender: TObject);
procedure YInBtnClick(Sender: TObject); procedure YInBtnClick(Sender: TObject);
procedure YOutBtnClick(Sender: TObject); procedure YOutBtnClick(Sender: TObject);
private private
{ private declarations }
procedure PlotXY(XPoints, YPoints, UpConf, LowConf: DblDyneVec; procedure PlotXY(XPoints, YPoints, UpConf, LowConf: DblDyneVec;
XMean, YMean, R, Slope, Intercept: Double); XMean, YMean, R, Slope, Intercept: Double);
protected protected
procedure AdjustConstraints; override; procedure AdjustConstraints; override;
procedure Compute; override; procedure Compute; override;
procedure UpdateBtnStates; override; procedure UpdateBtnStates; override;
function Validate(out AMsg: String; out AControl: TWinControl; function Validate(out AMsg: String; out AControl: TWinControl;
Xcol,Ycol: Integer): Boolean; reintroduce; Xcol,Ycol: Integer): Boolean; reintroduce;
public public
{ public declarations }
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
procedure Reset; override; procedure Reset; override;
end; end;
@ -82,6 +83,7 @@ begin
Marks.Source := TListChartSource.Create(self); Marks.Source := TListChartSource.Create(self);
Marks.Style := smsLabel; Marks.Style := smsLabel;
Grid.Visible := false; Grid.Visible := false;
TickColor := clNone;
end; end;
with FChartFrame.Chart.AxisList.Add do with FChartFrame.Chart.AxisList.Add do
begin begin
@ -89,6 +91,7 @@ begin
Marks.Source := TListChartSource.Create(self); Marks.Source := TListChartSource.Create(self);
Marks.Style := smsLabel; Marks.Style := smsLabel;
Grid.Visible := false; Grid.Visible := false;
TickColor := clNone;
end; end;
PageControl.ActivePage := ChartPage; PageControl.ActivePage := ChartPage;
@ -204,7 +207,7 @@ begin
t := InverseT(confBand, DF); t := InverseT(confBand, DF);
for i := 0 to N-1 do for i := 0 to N-1 do
begin begin
predicted := slope * xValues[i] + intercept; predicted := intercept + slope * xValues[i];
seData := sePred * sqrt(1.0 + 1/N + sqr(xValues[i] - XMean) / SXX); seData := sePred * sqrt(1.0 + 1/N + sqr(xValues[i] - XMean) / SXX);
upConf[i] := predicted + t * seData; upConf[i] := predicted + t * seData;
lowConf[i] := predicted - t * seData; lowConf[i] := predicted - t * seData;

View File

@ -1,107 +1,130 @@
object ResistanceLineForm: TResistanceLineForm inherited ResistanceLineForm: TResistanceLineForm
Left = 581 Left = 581
Height = 480 Height = 438
Top = 301 Top = 301
Width = 535 Width = 883
HelpType = htKeyword HelpType = htKeyword
HelpKeyword = 'html/ResistantLineforBivariateData.htm' HelpKeyword = 'html/ResistantLineforBivariateData.htm'
Caption = 'Resistant Line for Bivariate Data' Caption = 'Resistant Line for Bivariate Data'
ClientHeight = 480 ClientHeight = 438
ClientWidth = 535 ClientWidth = 883
OnActivate = FormActivate inherited ParamsPanel: TPanel
OnCreate = FormCreate Height = 422
OnShow = ResetBtnClick Width = 320
Position = poMainFormCenter ClientHeight = 422
LCLVersion = '2.0.10.0' ClientWidth = 320
object Label1: TLabel inherited CloseBtn: TButton
AnchorSideLeft.Control = Owner Left = 265
AnchorSideTop.Control = HorCenterBevel Top = 397
AnchorSideTop.Side = asrBottom TabOrder = 11
end
inherited ComputeBtn: TButton
Left = 181
Top = 397
TabOrder = 10
end
inherited ResetBtn: TButton
Left = 119
Top = 397
TabOrder = 9
end
inherited HelpBtn: TButton
Tag = 163
Left = 60
Top = 397
TabOrder = 8
end
inherited ButtonBevel: TBevel
Top = 381
Width = 320
end
object Label1: TLabel[5]
AnchorSideLeft.Control = VarList
AnchorSideTop.Control = ParamsPanel
Left = 8 Left = 8
Height = 15 Height = 15
Top = 144 Top = 0
Width = 46 Width = 46
BorderSpacing.Left = 8
Caption = 'Variables' Caption = 'Variables'
ParentColor = False ParentColor = False
end end
object Label2: TLabel object Label2: TLabel[6]
AnchorSideLeft.Control = XEdit AnchorSideLeft.Control = XEdit
AnchorSideTop.Control = Label1 AnchorSideTop.Control = Label1
Left = 188 Left = 181
Height = 15 Height = 15
Top = 144 Top = 0
Width = 93 Width = 93
Caption = 'Selected Variables' Caption = 'Selected Variables'
ParentColor = False ParentColor = False
end end
object Label3: TLabel object Label3: TLabel[7]
AnchorSideLeft.Control = XEdit AnchorSideLeft.Control = XEdit
AnchorSideBottom.Control = XEdit AnchorSideBottom.Control = XEdit
Left = 188 Left = 181
Height = 15 Height = 15
Top = 183 Top = 21
Width = 51 Width = 51
Anchors = [akLeft, akBottom] Anchors = [akLeft, akBottom]
BorderSpacing.Bottom = 2 BorderSpacing.Bottom = 2
Caption = 'X Variable' Caption = 'X Variable'
ParentColor = False ParentColor = False
end end
object Label4: TLabel object Label4: TLabel[8]
AnchorSideLeft.Control = YEdit AnchorSideLeft.Control = YEdit
AnchorSideBottom.Control = YEdit AnchorSideBottom.Control = YEdit
Left = 188 Left = 181
Height = 15 Height = 15
Top = 300 Top = 101
Width = 51 Width = 51
Anchors = [akLeft, akBottom] Anchors = [akLeft, akBottom]
BorderSpacing.Bottom = 2 BorderSpacing.Bottom = 2
Caption = 'Y Variable' Caption = 'Y Variable'
ParentColor = False ParentColor = False
end end
object XEdit: TEdit object XEdit: TEdit[9]
AnchorSideLeft.Control = XInBtn AnchorSideLeft.Control = XInBtn
AnchorSideLeft.Side = asrBottom AnchorSideLeft.Side = asrBottom
AnchorSideRight.Control = GroupBox1 AnchorSideRight.Control = ParamsPanel
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = XOutBtn AnchorSideBottom.Control = XOutBtn
AnchorSideBottom.Side = asrBottom AnchorSideBottom.Side = asrBottom
Left = 188 Left = 181
Height = 23 Height = 23
Top = 200 Top = 38
Width = 136 Width = 139
Anchors = [akLeft, akRight, akBottom] Anchors = [akLeft, akRight, akBottom]
BorderSpacing.Right = 16
BorderSpacing.Bottom = 12 BorderSpacing.Bottom = 12
ReadOnly = True ReadOnly = True
TabOrder = 3 TabOrder = 3
Text = 'XEdit' Text = 'XEdit'
end end
object YEdit: TEdit object YEdit: TEdit[10]
AnchorSideLeft.Control = XEdit AnchorSideLeft.Control = XEdit
AnchorSideRight.Control = XEdit AnchorSideRight.Control = XEdit
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = YOutBtn AnchorSideBottom.Control = YOutBtn
AnchorSideBottom.Side = asrBottom AnchorSideBottom.Side = asrBottom
Left = 188 Left = 181
Height = 23 Height = 23
Top = 317 Top = 118
Width = 136 Width = 139
Anchors = [akLeft, akRight, akBottom] Anchors = [akLeft, akRight, akBottom]
BorderSpacing.Bottom = 12 BorderSpacing.Bottom = 12
ReadOnly = True ReadOnly = True
TabOrder = 6 TabOrder = 6
Text = 'Edit1' Text = 'YEdit'
end end
object XInBtn: TBitBtn object XInBtn: TBitBtn[11]
AnchorSideLeft.Control = HorCenterBevel AnchorSideLeft.Control = ParamsPanel
AnchorSideLeft.Side = asrCenter AnchorSideLeft.Side = asrCenter
AnchorSideTop.Control = VarList
AnchorSideRight.Control = XEdit AnchorSideRight.Control = XEdit
AnchorSideBottom.Control = XOutBtn AnchorSideBottom.Control = XOutBtn
Left = 152 Left = 147
Height = 28 Height = 26
Top = 175 Top = 17
Width = 28 Width = 26
Anchors = [akLeft, akBottom]
BorderSpacing.Right = 8 BorderSpacing.Right = 8
BorderSpacing.Bottom = 4 BorderSpacing.Bottom = 4
Glyph.Data = { Glyph.Data = {
@ -146,16 +169,17 @@ object ResistanceLineForm: TResistanceLineForm
Spacing = 0 Spacing = 0
TabOrder = 1 TabOrder = 1
end end
object YInBtn: TBitBtn object YInBtn: TBitBtn[12]
AnchorSideLeft.Control = HorCenterBevel AnchorSideLeft.Control = ParamsPanel
AnchorSideLeft.Side = asrCenter AnchorSideLeft.Side = asrCenter
AnchorSideTop.Control = Bevel1 AnchorSideTop.Control = XOutBtn
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = YEdit AnchorSideRight.Control = YEdit
Left = 152 Left = 147
Height = 28 Height = 26
Top = 292 Top = 97
Width = 28 Width = 26
BorderSpacing.Top = 24
BorderSpacing.Right = 8 BorderSpacing.Right = 8
Glyph.Data = { Glyph.Data = {
36040000424D3604000000000000360000002800000010000000100000000100 36040000424D3604000000000000360000002800000010000000100000000100
@ -199,14 +223,14 @@ object ResistanceLineForm: TResistanceLineForm
Spacing = 0 Spacing = 0
TabOrder = 4 TabOrder = 4
end end
object XOutBtn: TBitBtn object XOutBtn: TBitBtn[13]
AnchorSideLeft.Control = XInBtn AnchorSideLeft.Control = XInBtn
AnchorSideBottom.Control = Bevel1 AnchorSideTop.Control = XInBtn
Left = 152 AnchorSideTop.Side = asrBottom
Height = 28 Left = 147
Top = 207 Height = 26
Width = 28 Top = 47
Anchors = [akLeft, akBottom] Width = 26
Glyph.Data = { Glyph.Data = {
36040000424D3604000000000000360000002800000010000000100000000100 36040000424D3604000000000000360000002800000010000000100000000100
2000000000000004000064000000640000000000000000000000FFFFFF00FFFF 2000000000000004000064000000640000000000000000000000FFFFFF00FFFF
@ -249,14 +273,14 @@ object ResistanceLineForm: TResistanceLineForm
Spacing = 0 Spacing = 0
TabOrder = 2 TabOrder = 2
end end
object YOutBtn: TBitBtn object YOutBtn: TBitBtn[14]
AnchorSideLeft.Control = YInBtn AnchorSideLeft.Control = YInBtn
AnchorSideTop.Control = YInBtn AnchorSideTop.Control = YInBtn
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
Left = 152 Left = 147
Height = 28 Height = 26
Top = 324 Top = 127
Width = 28 Width = 26
BorderSpacing.Top = 4 BorderSpacing.Top = 4
Glyph.Data = { Glyph.Data = {
36040000424D3604000000000000360000002800000010000000100000000100 36040000424D3604000000000000360000002800000010000000100000000100
@ -300,272 +324,184 @@ object ResistanceLineForm: TResistanceLineForm
Spacing = 0 Spacing = 0
TabOrder = 5 TabOrder = 5
end end
object ResetBtn: TButton object OptionsGroup: TGroupBox[15]
AnchorSideRight.Control = ComputeBtn AnchorSideLeft.Control = ParamsPanel
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
Left = 326
Height = 25
Top = 447
Width = 54
Anchors = [akRight, akBottom]
AutoSize = True
BorderSpacing.Left = 12
BorderSpacing.Top = 8
BorderSpacing.Right = 8
BorderSpacing.Bottom = 8
Caption = 'Reset'
OnClick = ResetBtnClick
TabOrder = 11
end
object ComputeBtn: TButton
AnchorSideRight.Control = CloseBtn
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
Left = 388
Height = 25
Top = 447
Width = 76
Anchors = [akRight, akBottom]
AutoSize = True
BorderSpacing.Top = 8
BorderSpacing.Right = 8
BorderSpacing.Bottom = 8
Caption = 'Compute'
OnClick = ComputeBtnClick
TabOrder = 12
end
object CloseBtn: TButton
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
Left = 472
Height = 25
Top = 447
Width = 55
Anchors = [akRight, akBottom]
AutoSize = True
BorderSpacing.Top = 8
BorderSpacing.Right = 8
BorderSpacing.Bottom = 8
Caption = 'Close'
ModalResult = 11
OnClick = CloseBtnClick
TabOrder = 13
end
object GroupBox1: TGroupBox
AnchorSideTop.Control = Label1 AnchorSideTop.Control = Label1
AnchorSideRight.Control = Owner AnchorSideTop.Side = asrBottom
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 340 AnchorSideBottom.Control = ButtonBevel
Height = 152 Left = 0
Top = 144 Height = 228
Width = 187 Top = 153
Anchors = [akTop, akRight] Width = 264
Anchors = [akLeft, akBottom]
AutoSize = True AutoSize = True
BorderSpacing.Right = 8 BorderSpacing.Right = 8
Caption = 'Options' Caption = 'Options'
ClientHeight = 132 ClientHeight = 208
ClientWidth = 183 ClientWidth = 260
Enabled = False
TabOrder = 7 TabOrder = 7
object Label5: TLabel object ConfLabel: TLabel
AnchorSideLeft.Control = GroupBox1 AnchorSideLeft.Control = OptionsGroup
AnchorSideTop.Control = ConfEdit AnchorSideTop.Control = ConfEdit
AnchorSideTop.Side = asrCenter AnchorSideTop.Side = asrCenter
Left = 32 Left = 32
Height = 15 Height = 15
Top = 101 Top = 131
Width = 74 Width = 74
BorderSpacing.Left = 32 BorderSpacing.Left = 32
Caption = '% Confidence' Caption = '% Confidence'
ParentColor = False ParentColor = False
end end
object DescChk: TCheckBox object DescChk: TCheckBox
AnchorSideLeft.Control = GroupBox1 AnchorSideLeft.Control = OptionsGroup
AnchorSideTop.Control = PointsChk AnchorSideTop.Control = ConfEdit
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
Left = 12 Left = 12
Height = 19 Height = 19
Top = 21 Top = 158
Width = 155 Width = 153
BorderSpacing.Left = 12 BorderSpacing.Left = 12
Caption = 'Print Descriptive Statistics' Caption = 'Print descriptive statistics'
TabOrder = 1 TabOrder = 7
end end
object ConfEdit: TEdit object ConfEdit: TEdit
AnchorSideLeft.Control = Label5 AnchorSideLeft.Control = ConfLabel
AnchorSideLeft.Side = asrBottom AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = ConfChk AnchorSideTop.Control = ConfChk
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
Left = 114 Left = 114
Height = 23 Height = 23
Top = 97 Top = 127
Width = 57 Width = 57
Alignment = taRightJustify Alignment = taRightJustify
BorderSpacing.Left = 8 BorderSpacing.Left = 8
BorderSpacing.Right = 12 BorderSpacing.Right = 12
BorderSpacing.Bottom = 12 BorderSpacing.Bottom = 8
TabOrder = 5 TabOrder = 5
Text = '95.0' Text = '95.0'
end end
object LineChk: TCheckBox object LineChk: TCheckBox
AnchorSideLeft.Control = GroupBox1 AnchorSideLeft.Control = OptionsGroup
AnchorSideTop.Control = DescChk AnchorSideTop.Control = OptionsBevel
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
Left = 12 Left = 12
Height = 19 Height = 19
Top = 40 Top = 70
Width = 146 Width = 146
BorderSpacing.Left = 12 BorderSpacing.Left = 12
BorderSpacing.Top = 12
Caption = 'Plot the Regression Line' Caption = 'Plot the Regression Line'
TabOrder = 2 TabOrder = 2
end end
object MeansChk: TCheckBox object MeansChk: TCheckBox
AnchorSideLeft.Control = GroupBox1 AnchorSideLeft.Control = OptionsGroup
AnchorSideTop.Control = LineChk AnchorSideTop.Control = LineChk
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
Left = 12 Left = 12
Height = 19 Height = 19
Top = 59 Top = 89
Width = 99 Width = 99
BorderSpacing.Left = 12 BorderSpacing.Left = 12
Caption = 'Plot the Means' Caption = 'Plot the Means'
TabOrder = 3 TabOrder = 3
end end
object ConfChk: TCheckBox object ConfChk: TCheckBox
AnchorSideLeft.Control = GroupBox1 AnchorSideLeft.Control = OptionsGroup
AnchorSideTop.Control = MeansChk AnchorSideTop.Control = MeansChk
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
Left = 12 Left = 12
Height = 19 Height = 19
Top = 78 Top = 108
Width = 155 Width = 155
BorderSpacing.Left = 12 BorderSpacing.Left = 12
Caption = 'Plot the Confidence Band' Caption = 'Plot the Confidence Band'
TabOrder = 4 TabOrder = 4
end end
object PointsChk: TCheckBox object GridChk: TCheckBox
AnchorSideLeft.Control = GroupBox1 AnchorSideLeft.Control = OptionsGroup
AnchorSideTop.Control = GroupBox1 AnchorSideTop.Control = DescChk
AnchorSideTop.Side = asrBottom
Left = 12 Left = 12
Height = 19 Height = 19
Top = 2 Top = 177
Width = 153 Width = 248
BorderSpacing.Left = 12 BorderSpacing.Left = 12
BorderSpacing.Top = 2 BorderSpacing.Bottom = 12
Caption = 'Plot All of the points First' Caption = 'Enter Predicted Y and Residual Y in the Grid'
TabOrder = 6
end
object PlotMediansChk: TRadioButton
AnchorSideLeft.Control = OptionsGroup
AnchorSideTop.Control = OptionsGroup
Left = 12
Height = 19
Top = 6
Width = 215
BorderSpacing.Left = 12
BorderSpacing.Top = 6
Caption = 'Plot the three medians and slope line'
OnChange = PlotMediansChkChange
TabOrder = 0 TabOrder = 0
end end
object PlotPointsChk: TRadioButton
AnchorSideLeft.Control = OptionsGroup
AnchorSideTop.Control = PlotMediansChk
AnchorSideTop.Side = asrBottom
Left = 12
Height = 19
Top = 27
Width = 146
BorderSpacing.Left = 12
BorderSpacing.Top = 2
Caption = 'Plot points and linear fit'
OnChange = PlotMediansChkChange
TabOrder = 1
end end
object VarList: TListBox object OptionsBevel: TBevel
AnchorSideLeft.Control = Owner AnchorSideLeft.Control = OptionsGroup
AnchorSideTop.Control = PlotPointsChk
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = OptionsGroup
AnchorSideRight.Side = asrBottom
Left = 12
Height = 12
Top = 46
Width = 236
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 12
BorderSpacing.Right = 12
Shape = bsBottomLine
end
end
object VarList: TListBox[16]
AnchorSideLeft.Control = ParamsPanel
AnchorSideTop.Control = Label1 AnchorSideTop.Control = Label1
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = XInBtn AnchorSideRight.Control = XInBtn
AnchorSideBottom.Control = StdCorChk AnchorSideBottom.Control = OptionsGroup
Left = 8 Left = 8
Height = 205 Height = 128
Top = 161 Top = 17
Width = 136 Width = 131
Anchors = [akTop, akLeft, akRight, akBottom] Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Left = 8 BorderSpacing.Left = 8
BorderSpacing.Top = 2 BorderSpacing.Top = 2
BorderSpacing.Right = 8 BorderSpacing.Right = 8
BorderSpacing.Bottom = 8 BorderSpacing.Bottom = 8
Constraints.MinHeight = 200
ItemHeight = 0 ItemHeight = 0
OnDblClick = VarListDblClick
OnSelectionChange = VarListSelectionChange OnSelectionChange = VarListSelectionChange
TabOrder = 0 TabOrder = 0
end end
object StdCorChk: TCheckBox
AnchorSideLeft.Control = Owner
AnchorSideBottom.Control = PlotMediansChk
Left = 8
Height = 19
Top = 374
Width = 330
Anchors = [akLeft, akBottom]
BorderSpacing.Left = 8
Caption = 'Option: Compute a standard product-moment correlation.'
OnChange = StdCorChkChange
TabOrder = 8
end end
object PlotMediansChk: TCheckBox inherited ParamsSplitter: TSplitter
AnchorSideLeft.Control = Owner Left = 332
AnchorSideBottom.Control = GridChk Height = 438
Left = 8
Height = 19
Top = 393
Width = 265
Anchors = [akLeft, akBottom]
BorderSpacing.Left = 8
Caption = 'Plot the Three Medians and Slope Line (in Red)'
TabOrder = 9
end end
object GridChk: TCheckBox inherited PageControl: TPageControl
AnchorSideLeft.Control = Owner Left = 341
AnchorSideBottom.Control = Bevel2 Height = 422
Left = 8 Width = 534
Height = 19
Top = 412
Width = 248
Anchors = [akLeft, akBottom]
BorderSpacing.Left = 8
Caption = 'Enter Predicted Y and Residual Y in the Grid'
TabOrder = 10
end
object Bevel1: TBevel
AnchorSideLeft.Control = YInBtn
AnchorSideLeft.Side = asrCenter
AnchorSideTop.Control = VarList
AnchorSideTop.Side = asrCenter
Left = 161
Height = 57
Top = 235
Width = 10
Shape = bsSpacer
end
object Bevel2: TBevel
AnchorSideLeft.Control = Owner
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
Left = 0
Height = 8
Top = 431
Width = 535
Anchors = [akLeft, akRight, akBottom]
Shape = bsBottomLine
end
object Memo1: TLabel
AnchorSideLeft.Control = Owner
AnchorSideTop.Control = Owner
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
Left = 8
Height = 120
Top = 8
Width = 519
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 8
BorderSpacing.Top = 8
BorderSpacing.Right = 8
Caption = 'The Resistant Line procedure creates three equal groups by sorting on the X variable and obtaining the median value of each group.'#13#10#13#10'The median values for these three groups on both the X and Y variables are then plotted. The line from the low group median to the middle group median is plotted as well as the line from the middle group to the top group median. A comparison of the slope of these two lines gives an indication of the degree to which the data fit a straight line. Enter the X and Y variables to be analyzed and click the compute button.'
ParentColor = False
WordWrap = True
end
object HorCenterBevel: TBevel
AnchorSideLeft.Control = VarList
AnchorSideTop.Control = Memo1
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = XEdit
AnchorSideRight.Side = asrBottom
Left = 8
Height = 16
Top = 128
Width = 316
Anchors = [akTop, akLeft, akRight]
Shape = bsSpacer
end end
end end

View File

@ -21,17 +21,17 @@ inherited DistribFrm: TDistribFrm
TabOrder = 6 TabOrder = 6
end end
inherited ComputeBtn: TButton inherited ComputeBtn: TButton
Left = 70 Left = 69
Top = 387 Top = 387
TabOrder = 5 TabOrder = 5
end end
inherited ResetBtn: TButton inherited ResetBtn: TButton
Left = 8 Left = 7
Top = 387 Top = 387
TabOrder = 4 TabOrder = 4
end end
inherited HelpBtn: TButton inherited HelpBtn: TButton
Left = -51 Left = -52
Top = 387 Top = 387
Visible = False Visible = False
end end

View File

@ -95,7 +95,6 @@ begin
FChartFrame.Chart.Legend.ColumnCount := 3; FChartFrame.Chart.Legend.ColumnCount := 3;
FChartFrame.Chart.Legend.TextFormat := tfHTML; FChartFrame.Chart.Legend.TextFormat := tfHTML;
// InitToolbar(FChartFrame.ChartToolbar, tpTop);
tbErase := TToolButton.Create(self); tbErase := TToolButton.Create(self);
tbErase.ImageIndex := 6; tbErase.ImageIndex := 6;
tbErase.Caption := 'Erase'; tbErase.Caption := 'Erase';

View File

@ -14,6 +14,8 @@ function CollectValues(AGrid: TStringGrid; AColIndex: Integer;
procedure GetMinMax(AGrid: TStringGrid; AColIndex: Integer; procedure GetMinMax(AGrid: TStringGrid; AColIndex: Integer;
const AColCheck: IntDyneVec; out AMin, AMax: Double); const AColCheck: IntDyneVec; out AMin, AMax: Double);
function GetVariableIndex(AGrid: TStringGrid; const AVarName: String): Integer;
function GoodRecord(AGrid: TStringGrid; ARow: integer; function GoodRecord(AGrid: TStringGrid; ARow: integer;
const AColCheck: IntDyneVec): boolean; const AColCheck: IntDyneVec): boolean;
@ -93,6 +95,14 @@ begin
end; end;
{ Finds the index of the variable with the specified name among the columns of
the grid. }
function GetVariableIndex(AGrid: TStringGrid; const AVarName: String): Integer;
begin
Result := AGrid.Rows[0].IndexOf(AVarName);
end;
{ Checks whether all cells specified for the given row in the columns listed in { Checks whether all cells specified for the given row in the columns listed in
the GridPos array are "valid": not filtered and not empty } the GridPos array are "valid": not filtered and not empty }
function GoodRecord(AGrid: TStringGrid; ARow: integer; function GoodRecord(AGrid: TStringGrid; ARow: integer;

View File

@ -51,11 +51,14 @@ procedure Calc_MeanVarStdDev(const AData: DblDyneVec; out AMean, AVariance, AStd
procedure Calc_MeanVarStdDevSS(const AData: DblDyneVec; out AMean, AVariance, AStdDev, ASumOfSquares: Double); procedure Calc_MeanVarStdDevSS(const AData: DblDyneVec; out AMean, AVariance, AStdDev, ASumOfSquares: Double);
procedure Calc_SumSS(const AData: DblDyneVec; out Sum, SS: Double); procedure Calc_SumSS(const AData: DblDyneVec; out Sum, SS: Double);
function Calc_Median(const AData: DblDyneVec): Double;
implementation implementation
uses uses
Math; Math,
Utils;
// Calculates the error function // Calculates the error function
// /x // /x
@ -572,6 +575,21 @@ begin
end; end;
function Calc_Median(const AData: DblDyneVec): Double;
var
N, midPt: integer;
begin
SortOnX(AData);
N := Length(AData);
midPt := N div 2;
if odd(N) then
Result := AData[midPt] // odd no. of values
else
Result := (AData[midPt-1] + AData[midPt]) / 2; // even no. of values
end;
initialization initialization
InitFactLn(); InitFactLn();