LazStats: Inherit form in StemLeafUnit from TBasicStatsParamsForm. Minor refactoring.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7761 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2020-10-10 17:53:35 +00:00
parent cd11e879cf
commit 65ee7405e5
7 changed files with 251 additions and 347 deletions

View File

@ -49,7 +49,7 @@ correlation, means, standard deviations and confidence interval for each correla
145=Directions: First click on the variable name that represents the sample lot number. Next, click on the variable that represents the measurement. Click the Compute Button to obtain the results. NOTE! Equal group (lot) sizes of 2 to 25 required for Sigma analysis. Control limits are plus and minus 3 sigma. Up to 200 lots may be analyzed. 145=Directions: First click on the variable name that represents the sample lot number. Next, click on the variable that represents the measurement. Click the Compute Button to obtain the results. NOTE! Equal group (lot) sizes of 2 to 25 required for Sigma analysis. Control limits are plus and minus 3 sigma. Up to 200 lots may be analyzed.
146=Description: Straight Line Depreciation calculates the depreciation allowance for an asset over one period in it's life. The function divides the cost minus the salvage value by the number of years of useful life of the asset. Cost is the inital amount paid for the asset. Salvage is the value left at the end of the asset's life. EXAMPLE: What is the depreciation value on might expect for a computer purchased for $2,000.00 and expected to have a useful life of three years with no residual value? ANSWER: Approximately $666.67 146=Description: Straight Line Depreciation calculates the depreciation allowance for an asset over one period in it's life. The function divides the cost minus the salvage value by the number of years of useful life of the asset. Cost is the inital amount paid for the asset. Salvage is the value left at the end of the asset's life. EXAMPLE: What is the depreciation value on might expect for a computer purchased for $2,000.00 and expected to have a useful life of three years with no residual value? ANSWER: Approximately $666.67
147=R = Kr / (1 + (K - 1) r where R is the estimated reliability of a test when increased by a factor of K. K is the number of items in the lengthened test divided by the number of items in the original test. r is the reliability of the original test. 147=R = Kr / (1 + (K - 1) r where R is the estimated reliability of a test when increased by a factor of K. K is the number of items in the lengthened test divided by the number of items in the original test. r is the reliability of the original test.
148=Directions: Click on the variables from the left list of available variables. Click the right-pointing arrow to enter your selection(s). You can remove a selected variable by clicking on it and click the left-pointing arrow button. Click the Compute button to do the analysis. NOTE: Some leaves may represent fragments smaller than the leaf depth. 148=Click on the variables from the left list of available variables.\nClick the right-pointing arrow to enter your selection(s).\nYou can remove a selected variable by clicking on it and click the left-pointing arrow button.\nClick the Compute button to do the analysis.\n\nNOTE:\nSome leaves may represent fragments smaller than the leaf depth.
149=Description: Sum of Years Digits Depreciation calculates depreciation amounts for an asset using an accelerated depreciation method. This allows for higher depreciation in the early years of an asset's life. Cost is the initial cost of the asset. Salvage is the value of the asset at the end of it's life expectancy. Life is the length of the asset's life expectancy. Period is the period that you wish to calculate the depreciation. EXAMPLE: What is the depreciation for period 1, 2 or 3 that one can claim for a computer purchased at a price of $2,000.00 and expected to have a useful life of 3 years with no salvage value? ANSWER: $1,000.00 the first year, $666.67 the second period and $333.33 the last year. 149=Description: Sum of Years Digits Depreciation calculates depreciation amounts for an asset using an accelerated depreciation method. This allows for higher depreciation in the early years of an asset's life. Cost is the initial cost of the asset. Salvage is the value of the asset at the end of it's life expectancy. Life is the length of the asset's life expectancy. Period is the period that you wish to calculate the depreciation. EXAMPLE: What is the depreciation for period 1, 2 or 3 that one can claim for a computer purchased at a price of $2,000.00 and expected to have a useful life of 3 years with no salvage value? ANSWER: $1,000.00 the first year, $666.67 the second period and $333.33 the last year.
150=New variables may be created that are transformations of an existing variable or a combination of two variables or a variable and a constant. For example, you may want to create a new variable that is the natural log of an existing variable. As another example, you may want to create a variable that is the product of two other variables. To create the new variable, enter a name for the new variable in the edit box provided for the new variable name. Next, select the transformation in the list of functions available. The selected transformation will be shown in a box below the list of functions. Next, click on the name of the variable for the first arguement of the function to be performed and use the corresponding right arrow button to enter it. If a second variable is required (V2) click on the name of the variable and enter it with the corresponding arrow for V2. If a constant is required, click on the constant edit box and enter the value. Click on the Compute button. 150=New variables may be created that are transformations of an existing variable or a combination of two variables or a variable and a constant. For example, you may want to create a new variable that is the natural log of an existing variable. As another example, you may want to create a variable that is the product of two other variables. To create the new variable, enter a name for the new variable in the edit box provided for the new variable name. Next, select the transformation in the list of functions available. The selected transformation will be shown in a box below the list of functions. Next, click on the name of the variable for the first arguement of the function to be performed and use the corresponding right arrow button to enter it. If a second variable is required (V2) click on the name of the variable and enter it with the corresponding arrow for V2. If a constant is required, click on the constant edit box and enter the value. Click on the Compute button.
151=Directions: For Dependent samples, click on the three variables representing X, Y and Z (in that order.) The test will compare the r(x,y) with the r(x,z). For Independent samples, click on the X and Y variables to be correlated and then the variable representing the group coding variable. The correlations obtained in each of two groups will be compared. 151=Directions: For Dependent samples, click on the three variables representing X, Y and Z (in that order.) The test will compare the r(x,y) with the r(x,z). For Independent samples, click on the X and Y variables to be correlated and then the variable representing the group coding variable. The correlations obtained in each of two groups will be compared.
@ -64,4 +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. 163=The Resistant Line procedure creates three equal groups by sorting on the X variable and obtaining the median value of each group.\n\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

@ -280,7 +280,7 @@
<Unit22> <Unit22>
<Filename Value="forms\analysis\descriptive\stemleafunit.pas"/> <Filename Value="forms\analysis\descriptive\stemleafunit.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<ComponentName Value="StemLeafFrm"/> <ComponentName Value="StemLeafForm"/>
<HasResources Value="True"/> <HasResources Value="True"/>
<ResourceBaseClass Value="Form"/> <ResourceBaseClass Value="Form"/>
<UnitName Value="StemLeafUnit"/> <UnitName Value="StemLeafUnit"/>

View File

@ -1,57 +1,53 @@
object StemLeafFrm: TStemLeafFrm inherited StemLeafForm: TStemLeafForm
Left = 519 Height = 339
Height = 296
Top = 257 Top = 257
Width = 407 Width = 684
HelpType = htKeyword HelpType = htKeyword
HelpKeyword = 'html/StemandLeafPlot.htm' HelpKeyword = 'html/StemandLeafPlot.htm'
AutoSize = True
Caption = 'Stem and Leaf Analysis' Caption = 'Stem and Leaf Analysis'
ClientHeight = 296 ClientHeight = 339
ClientWidth = 407 ClientWidth = 684
OnActivate = FormActivate inherited ParamsPanel: TPanel
OnCreate = FormCreate Height = 323
OnShow = FormShow ClientHeight = 323
Position = poMainFormCenter inherited CloseBtn: TButton
LCLVersion = '2.0.10.0' Top = 298
object TestChk: TCheckBox TabOrder = 9
AnchorSideLeft.Control = Owner end
AnchorSideBottom.Control = Bevel1 inherited ComputeBtn: TButton
Top = 298
TabOrder = 8
end
inherited ResetBtn: TButton
Top = 298
TabOrder = 7
end
inherited HelpBtn: TButton
Tag = 148
Top = 298
TabOrder = 6
end
inherited ButtonBevel: TBevel
Top = 282
end
object TestChk: TCheckBox[5]
AnchorSideLeft.Control = ParamsPanel
AnchorSideTop.Side = asrBottom
AnchorSideBottom.Control = ButtonBevel
AnchorSideBottom.Side = asrBottom AnchorSideBottom.Side = asrBottom
Left = 8 Left = 0
Height = 19 Height = 19
Top = 228 Top = 263
Width = 202 Width = 202
Anchors = [akLeft, akBottom] Anchors = [akLeft, akBottom]
BorderSpacing.Left = 8 BorderSpacing.Top = 8
BorderSpacing.Bottom = 8 BorderSpacing.Bottom = 8
Caption = 'Show All Scaled Values and Srrings' Caption = 'Show All Scaled Values and Srrings'
TabOrder = 0 TabOrder = 5
end end
object Panel1: TPanel object Label1: TLabel[6]
AnchorSideLeft.Control = Owner AnchorSideLeft.Control = ParamsPanel
AnchorSideTop.Control = Owner AnchorSideTop.Control = ParamsPanel
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = TestChk
Left = 8
Height = 212
Top = 8
Width = 391
Anchors = [akTop, akLeft, akRight, akBottom]
AutoSize = True
BorderSpacing.Left = 8
BorderSpacing.Top = 8
BorderSpacing.Right = 8
BorderSpacing.Bottom = 8
BevelOuter = bvNone
ClientHeight = 212
ClientWidth = 391
Constraints.MinHeight = 200
TabOrder = 1
object Label1: TLabel
AnchorSideLeft.Control = Panel1
AnchorSideTop.Control = Panel1
Left = 0 Left = 0
Height = 15 Height = 15
Top = 0 Top = 0
@ -59,48 +55,46 @@ object StemLeafFrm: TStemLeafFrm
Caption = 'Available Variables:' Caption = 'Available Variables:'
ParentColor = False ParentColor = False
end end
object VarList: TListBox object VarList: TListBox[7]
AnchorSideLeft.Control = Panel1 AnchorSideLeft.Control = ParamsPanel
AnchorSideTop.Control = Label1 AnchorSideTop.Control = Label1
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = AllBtn AnchorSideRight.Control = AllBtn
AnchorSideBottom.Control = Panel1 AnchorSideBottom.Control = TestChk
AnchorSideBottom.Side = asrBottom
Left = 0 Left = 0
Height = 195 Height = 238
Top = 17 Top = 17
Width = 167 Width = 121
Anchors = [akTop, akLeft, akRight, akBottom] Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Top = 2 BorderSpacing.Top = 2
BorderSpacing.Right = 8 BorderSpacing.Right = 4
ItemHeight = 0 ItemHeight = 0
MultiSelect = True MultiSelect = True
OnDblClick = VarListDblClick
OnSelectionChange = VarListSelectionChange OnSelectionChange = VarListSelectionChange
TabOrder = 0 TabOrder = 0
end end
object InBtn: TBitBtn object InBtn: TBitBtn[8]
AnchorSideLeft.Control = Panel1 AnchorSideLeft.Control = ParamsPanel
AnchorSideLeft.Side = asrCenter AnchorSideLeft.Side = asrCenter
AnchorSideTop.Control = VarList Left = 132
Left = 181 Height = 26
Height = 28
Top = 17 Top = 17
Width = 28 Width = 26
Images = MainDataModule.ImageList Images = MainDataModule.ImageList
ImageIndex = 1 ImageIndex = 1
OnClick = InBtnClick OnClick = InBtnClick
Spacing = 0 Spacing = 0
TabOrder = 1 TabOrder = 1
end end
object OutBtn: TBitBtn object OutBtn: TBitBtn[9]
AnchorSideLeft.Control = Panel1 AnchorSideLeft.Control = ParamsPanel
AnchorSideLeft.Side = asrCenter AnchorSideLeft.Side = asrCenter
AnchorSideTop.Control = InBtn
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
Left = 181 Left = 132
Height = 28 Height = 26
Top = 49 Top = 47
Width = 28 Width = 26
BorderSpacing.Top = 4 BorderSpacing.Top = 4
Images = MainDataModule.ImageList Images = MainDataModule.ImageList
ImageIndex = 0 ImageIndex = 0
@ -108,14 +102,13 @@ object StemLeafFrm: TStemLeafFrm
Spacing = 0 Spacing = 0
TabOrder = 2 TabOrder = 2
end end
object AllBtn: TBitBtn object AllBtn: TBitBtn[10]
AnchorSideLeft.Control = Panel1 AnchorSideLeft.Control = ParamsPanel
AnchorSideLeft.Side = asrCenter AnchorSideLeft.Side = asrCenter
AnchorSideTop.Control = OutBtn
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
Left = 175 Left = 125
Height = 25 Height = 25
Top = 101 Top = 97
Width = 40 Width = 40
AutoSize = True AutoSize = True
BorderSpacing.Top = 24 BorderSpacing.Top = 24
@ -123,128 +116,42 @@ object StemLeafFrm: TStemLeafFrm
OnClick = AllBtnClick OnClick = AllBtnClick
TabOrder = 3 TabOrder = 3
end end
object Label2: TLabel object Label2: TLabel[11]
AnchorSideLeft.Control = SelectList AnchorSideLeft.Control = SelectList
AnchorSideTop.Control = Panel1 AnchorSideTop.Control = ParamsPanel
AnchorSideRight.Control = Panel1 AnchorSideRight.Control = ParamsPanel
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 223 Left = 169
Height = 15 Height = 15
Top = 0 Top = 0
Width = 96 Width = 96
Caption = 'Selected Variables:' Caption = 'Selected Variables:'
ParentColor = False ParentColor = False
end end
object SelectList: TListBox object SelectList: TListBox[12]
AnchorSideLeft.Control = AllBtn AnchorSideLeft.Control = AllBtn
AnchorSideLeft.Side = asrBottom AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = Label2 AnchorSideTop.Control = Label2
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = Panel1 AnchorSideRight.Control = ParamsPanel
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = Panel1 AnchorSideBottom.Control = VarList
AnchorSideBottom.Side = asrBottom AnchorSideBottom.Side = asrBottom
Left = 223 Left = 169
Height = 195 Height = 238
Top = 17 Top = 17
Width = 168 Width = 122
Anchors = [akTop, akLeft, akRight, akBottom] Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Left = 8 BorderSpacing.Left = 4
BorderSpacing.Top = 2 BorderSpacing.Top = 2
ItemHeight = 0 ItemHeight = 0
MultiSelect = True MultiSelect = True
OnDblClick = SelectListDblClick
OnSelectionChange = VarListSelectionChange OnSelectionChange = VarListSelectionChange
TabOrder = 4 TabOrder = 4
end end
end end
object CloseBtn: TButton inherited ParamsSplitter: TSplitter
AnchorSideTop.Side = asrBottom Height = 339
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
Left = 340
Height = 25
Top = 263
Width = 55
Anchors = [akRight, akBottom]
AutoSize = True
BorderSpacing.Left = 8
BorderSpacing.Top = 8
BorderSpacing.Right = 12
BorderSpacing.Bottom = 8
Caption = 'Close'
ModalResult = 11
OnClick = CloseBtnClick
TabOrder = 2
end
object ComputeBtn: TButton
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = CloseBtn
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
Left = 256
Height = 25
Top = 263
Width = 76
Anchors = [akRight, akBottom]
AutoSize = True
BorderSpacing.Left = 8
BorderSpacing.Top = 8
BorderSpacing.Right = 8
BorderSpacing.Bottom = 8
Caption = 'Compute'
OnClick = ComputeBtnClick
TabOrder = 3
end
object ResetBtn: TButton
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = ComputeBtn
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
Left = 194
Height = 25
Top = 263
Width = 54
Anchors = [akRight, akBottom]
AutoSize = True
BorderSpacing.Left = 8
BorderSpacing.Top = 8
BorderSpacing.Right = 8
BorderSpacing.Bottom = 8
Caption = 'Reset'
OnClick = ResetBtnClick
TabOrder = 4
end
object HelpBtn: TButton
Tag = 148
AnchorSideRight.Control = ResetBtn
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
Left = 135
Height = 25
Top = 263
Width = 51
Anchors = [akRight, akBottom]
AutoSize = True
BorderSpacing.Left = 12
BorderSpacing.Top = 8
BorderSpacing.Right = 8
BorderSpacing.Bottom = 8
Caption = 'Help'
OnClick = HelpBtnClick
TabOrder = 5
end
object Bevel1: TBevel
AnchorSideLeft.Control = Owner
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = CloseBtn
Left = 0
Height = 8
Top = 247
Width = 407
Anchors = [akLeft, akRight, akBottom]
Shape = bsBottomLine
end end
end end

View File

@ -5,84 +5,74 @@ unit StemLeafUnit;
interface interface
uses uses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
StdCtrls, ExtCtrls, Buttons, Math, Clipbrd, StdCtrls, ExtCtrls, Buttons, Math, Clipbrd,
MainUnit, Globals, OutputUnit, DataProcs, ContextHelpUnit; MainUnit, Globals, BasicStatsReportFormUnit;
type type
{ TStemLeafForm }
{ TStemLeafFrm } TStemLeafForm = class(TBasicStatsReportForm)
TStemLeafFrm = class(TForm)
Bevel1: TBevel;
HelpBtn: TButton;
InBtn: TBitBtn; InBtn: TBitBtn;
OutBtn: TBitBtn; OutBtn: TBitBtn;
AllBtn: TBitBtn; AllBtn: TBitBtn;
Panel1: TPanel;
ResetBtn: TButton;
ComputeBtn: TButton;
CloseBtn: TButton;
TestChk: TCheckBox; TestChk: TCheckBox;
Label1: TLabel; Label1: TLabel;
Label2: TLabel; Label2: TLabel;
VarList: TListBox; VarList: TListBox;
SelectList: TListBox; SelectList: TListBox;
procedure AllBtnClick(Sender: TObject); procedure AllBtnClick(Sender: TObject);
procedure CloseBtnClick(Sender: TObject);
procedure ComputeBtnClick(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure HelpBtnClick(Sender: TObject);
procedure InBtnClick(Sender: TObject); procedure InBtnClick(Sender: TObject);
procedure OutBtnClick(Sender: TObject); procedure OutBtnClick(Sender: TObject);
procedure ResetBtnClick(Sender: TObject); procedure SelectListDblClick(Sender: TObject);
procedure VarListSelectionChange(Sender: TObject; User: boolean); procedure VarListDblClick(Sender: TObject);
procedure VarListSelectionChange(Sender: TObject; {%H-}User: boolean);
private private
{ private declarations }
FAutoSized: Boolean; protected
procedure UpdateBtnStates; procedure AdjustConstraints; override;
procedure Compute; override;
procedure UpdateBtnStates; override;
public public
{ public declarations } constructor Create(AOwner: TComponent); override;
procedure Reset; override;
end; end;
var var
StemLeafFrm: TStemLeafFrm; StemLeafForm: TStemLeafForm;
implementation implementation
{ TStemLeafFrm } {$R *.lfm}
procedure TStemLeafFrm.ResetBtnClick(Sender: TObject); uses
var Utils, MathUnit, GridProcs;
i: integer;
{ TStemLeafForm }
constructor TStemLeafForm.Create(AOwner: TComponent);
begin begin
VarList.Clear; inherited;
for i := 1 to NoVariables do
VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]); FReportFrame.BorderSpacing.Right := 0;
SelectList.Clear;
UpdateBtnStates;
end; end;
procedure TStemLeafFrm.FormCreate(Sender: TObject);
procedure TStemLeafForm.AdjustConstraints;
begin begin
Assert(OS3MainFrm <> nil); inherited;
ParamsPanel.Constraints.MinWidth := 4*CloseBtn.Width + 3*CloseBtn.BorderSpacing.Left;
ParamsPanel.Constraints.MinHeight := AllBtn.Top + AllBtn.Height +
TestChk.BorderSpacing.Top + TestChk.Height +
ButtonBevel.Height + CloseBtn.BorderSpacing.Top + CloseBtn.Height;
end; end;
procedure TStemLeafFrm.FormShow(Sender: TObject);
begin
ResetBtnClick(self);
end;
procedure TStemLeafFrm.HelpBtnClick(Sender: TObject); procedure TStemLeafForm.AllBtnClick(Sender: TObject);
begin
if ContextHelpForm = nil then
Application.CreateForm(TContextHelpForm, ContextHelpForm);
ContextHelpForm.HelpMessage((Sender as TButton).Tag);
end;
procedure TStemLeafFrm.AllBtnClick(Sender: TObject);
var var
i: integer; i: integer;
begin begin
@ -92,47 +82,38 @@ begin
UpdateBtnStates; UpdateBtnStates;
end; end;
procedure TStemLeafFrm.CloseBtnClick(Sender: TObject);
begin
Close;
end;
procedure TStemLeafFrm.ComputeBtnClick(Sender: TObject); procedure TStemLeafForm.Compute;
var var
i, j, k, L, ncases, noselected, largest, smallest: integer; i, j, k, L, ncases, noselected, largest, smallest: integer;
minsize, maxsize, stem, minstem, maxstem, bin, index: integer; minsize, maxsize, stem, minstem, maxstem, bin, index: integer;
leafvalue, counter, smallcount, testvalue, largestcount: integer; leafvalue, counter, smallcount, testvalue, largestcount: integer;
cellstring, outline, astring: string; outline, astring: string;
selected: IntDyneVec; selected: IntDyneVec = nil;
bins: IntDyneVec; bins: IntDyneVec = nil;
frequency: IntDyneVec; frequency: IntDyneVec = nil;
ValueString: StrDyneVec; ValueString: StrDyneVec = nil;
values: DblDyneVec; values: DblDyneVec = nil;
leafcount: IntDyneMat; leafCount: IntDyneMat = nil;
min, max, temp, X, stemsize: double; min, max, stemsize: double;
lReport: TStrings; lReport: TStrings;
begin begin
noselected := SelectList.Items.Count; noselected := SelectList.Items.Count;
if (noselected = 0) then if (noselected = 0) then
begin begin
MessageDlg('No variables were selected.', mtError, [mbOK], 0); ErrorMsg('No variables were selected.');
exit; exit;
end; end;
SetLength(selected, noselected); SetLength(selected, noselected);
SetLength(values,NoCases);
SetLength(bins, 100); SetLength(bins, 100);
SetLength(frequency, 100); SetLength(frequency, 100);
SetLength(ValueString,NoCases); SetLength(leafCount, 100,10);
SetLength(leafcount,100,10);
// Get selected variables // Get column indices of selected variables
for i := 1 to noselected do for i := 0 to noselected - 1 do
begin selected[i] := GetVariableIndex(OS3MainFrm.DataGrid, SelectList.Items[i]);
cellstring := SelectList.Items.Strings[i-1];
for j := 1 to NoVariables do
if (cellstring = OS3MainFrm.DataGrid.Cells[j,0]) then selected[i-1] := j;
end;
lReport := TStringList.Create; lReport := TStringList.Create;
try try
@ -143,24 +124,23 @@ begin
for j := 0 to noselected - 1 do for j := 0 to noselected - 1 do
begin begin
k := selected[j]; k := selected[j];
lReport.Add('Stem and Leaf Plot for variable: %s', [OS3MainFrm.DataGrid.Cells[k,0]]); lReport.Add('Stem and Leaf Plot for variable "%s"', [OS3MainFrm.DataGrid.Cells[k, 0]]);
ncases := 0; lReport.Add('');
min := 1.0e308;
max := -1.0e308;
minsize := 1000;
maxsize := -1000;
// Store values of the variable // Stores values of the variable
for i := 1 to NoCases do values := CollectValues(OS3MainFrm.DataGrid, k);
nCases := Length(values);
SetLength(valueString, nCases);
Calc_MaxMin(values, max, min);
minSize := MaxInt;
maxSize := -Maxint;
for i := 0 to High(values) do
begin begin
if not ValidValue(i,k) then continue; valueString[i] := Trim(OS3MainFrm.DataGrid.Cells[k, i]);
values[ncases] := StrToFloat(OS3MainFrm.DataGrid.Cells[k,i]); maxSize := Math.Max(maxSize, Length(valueString[i]));
ValueString[ncases] := Trim(OS3MainFrm.DataGrid.Cells[k,i]); minSize := Math.Min(minSize, Length(valueString[i]));
if (values[ncases] < min) then min := values[ncases];
if (values[ncases] > max) then max := values[ncases];
if Length(ValueString[ncases]) > maxsize then maxsize := Length(ValueString[ncases]);
if Length(ValueString[ncases]) < minsize then minsize := Length(ValueString[ncases]);
ncases := ncases + 1;
end; end;
largest := ceil(max); largest := ceil(max);
@ -190,16 +170,13 @@ begin
// multiply values by 10, round and save value divided by 10 // multiply values by 10, round and save value divided by 10
for i := 0 to ncases - 1 do for i := 0 to ncases - 1 do
begin begin
temp := floor(values[i] * 10); values[i] := floor(values[i] * 10) / 10;;
temp := temp / 10.0; ValueString[i] := Format('%4.1f', [values[i]]);
values[i] := temp;
astring := format('%4.1f',[values[i]]);
ValueString[i] := astring;
end; end;
// get max and min stem values for creating bins for stem values // get max and min stem values for creating bins for stem values
minstem := 999; minstem := MaxInt;
maxstem := -999; maxstem := -MaxInt;
for i := 0 to ncases - 1 do for i := 0 to ncases - 1 do
begin begin
stem := floor(values[i]); stem := floor(values[i]);
@ -218,30 +195,27 @@ begin
begin begin
if (values[i] > values[k]) then // swap values if (values[i] > values[k]) then // swap values
begin begin
X := values[i]; Exchange(values[i], values[k]);
values[i] := values[k]; Exchange(valueString[i], valueString[k]);
values[k] := X;
cellstring := ValueString[i];
ValueString[i] := ValueString[k];
ValueString[k] := cellstring;
end; end;
end; end;
end; end;
(* {
// check sizes - delete if ok // check sizes - delete if ok
outline := format('maxsize, minsize,stemsize: %10d %10d %10.2f',[maxsize, minsize, stemsize]); outline := format('maxsize, minsize,stemsize: %10d %10d %10.2f',[maxsize, minsize, stemsize]);
OutputFrm.RichEdit.Lines.Add(outline); OutputFrm.RichEdit.Lines.Add(outline);
OutputFrm.ShowModal; OutputFrm.ShowModal;
OutputFrm.RichEdit.Clear; OutputFrm.RichEdit.Clear;
*) }
if TestChk.Checked then if TestChk.Checked then
begin // test output begin // test output
lReport.Add('value ValueString'); lReport.Add(' Value ValueString');
lReport.Add('---------- --------------------');
for i := 0 to ncases - 1 do for i := 0 to ncases - 1 do
lReport.Add('%10.1f %s',[values[i],ValueString[i]]); lReport.Add('%10.1f %s', [values[i], valueString[i]]);
lReport.Add('');
end; end;
lReport.Add('');
lReport.Add('Frequency Stem & Leaf'); lReport.Add('Frequency Stem & Leaf');
// initialize leaf count for the bins // initialize leaf count for the bins
@ -259,7 +233,7 @@ begin
frequency[bin] := frequency[bin] + 1; // count number of stem values frequency[bin] := frequency[bin] + 1; // count number of stem values
end else end else
begin begin
MessageDlg('Error in bin value', mtError, [mbOK], 0); ErrorMsg('Error in bin value');
exit; exit;
end; end;
@ -271,13 +245,13 @@ begin
leafcount[bin,leafvalue] := leafcount[bin,leafvalue] + 1 leafcount[bin,leafvalue] := leafcount[bin,leafvalue] + 1
else else
begin begin
MessageDlg('Error in leafvalue', mtError, [mbOK], 0); ErrorMsg('Error in leafvalue');
exit; exit;
end; end;
end; end;
// get max leaf counters // get max leaf counters
largestcount := 0; largestCount := 0;
for i := 0 to 99 do // bin for i := 0 to 99 do // bin
begin begin
if frequency[i] = 0 then continue; // skip empty bins if frequency[i] = 0 then continue; // skip empty bins
@ -289,23 +263,23 @@ begin
end; end;
// determine leaf depth needed to get counter <= 50 // determine leaf depth needed to get counter <= 50
if (largestcount > 50) then if (largestCount > 50) then
begin begin
smallcount := 2; smallCount := 2;
testvalue := largestcount; testvalue := largestCount;
while (testvalue > 50) do while (testvalue > 50) do
begin begin
testvalue := largestcount div smallcount; testvalue := largestCount div smallCount;
smallcount := smallcount + 1; smallCount := smallCount + 1;
end; end;
smallcount := smallcount - 1; // leaf depth needed to reduce line lengths to 50 or less smallCount := smallCount - 1; // leaf depth needed to reduce line lengths to 50 or less
end else end else
smallcount := 1; smallCount := 1;
// rescale leafs // rescale leafs
for i := 0 to 99 do // bin for i := 0 to 99 do // bin
for k := 0 to 9 do // leaf for k := 0 to 9 do // leaf
leafcount[i,k] := leafcount[i,k] div smallcount; leafCount[i,k] := leafCount[i,k] div smallcount;
// plot results // plot results
for i := 0 to 99 do for i := 0 to 99 do
@ -314,8 +288,8 @@ begin
outline := format('%6d %3d ',[frequency[i], bins[i]]); outline := format('%6d %3d ',[frequency[i], bins[i]]);
for k := 0 to 9 do for k := 0 to 9 do
begin begin
if leafcount[i,k] = 0 then continue; if leafCount[i,k] = 0 then continue;
for L := 1 to leafcount[i,k] do for L := 1 to leafCount[i,k] do
outline := outline + Format('%d',[k]); outline := outline + Format('%d',[k]);
end; end;
lReport.Add(outline); lReport.Add(outline);
@ -329,43 +303,19 @@ begin
lReport.Add('Max. Value: %8.3f', [max]); lReport.Add('Max. Value: %8.3f', [max]);
lReport.Add('No. of good cases: %8d', [ncases]); lReport.Add('No. of good cases: %8d', [ncases]);
lReport.Add(''); lReport.Add('');
lReport.Add('-------------------------------------------------------------'); lReport.Add(DIVIDER_SMALL);
lReport.Add(''); lReport.Add('');
end; // next jth variable end;
DisplayReport(lReport); FReportFrame.DisplayReport(lReport);
finally finally
lReport.Free; lReport.Free;
frequency := nil;
bins := nil;
ValueString := nil;
values := nil;
selected := nil;
leafcount := nil;
end; end;
end; end;
procedure TStemLeafFrm.FormActivate(Sender: TObject);
var
w: Integer;
begin
if FAutoSized then
exit;
w := MaxValue([HelpBtn.Width, ResetBtn.Width, ComputeBtn.Width, CloseBtn.Width]); procedure TStemLeafForm.InBtnClick(Sender: TObject);
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 TStemLeafFrm.InBtnClick(Sender: TObject);
var var
i: integer; i: integer;
begin begin
@ -383,7 +333,8 @@ begin
UpdateBtnStates; UpdateBtnStates;
end; end;
procedure TStemLeafFrm.OutBtnClick(Sender: TObject);
procedure TStemLeafForm.OutBtnClick(Sender: TObject);
var var
i: integer; i: integer;
begin begin
@ -400,11 +351,41 @@ begin
UpdateBtnStates; UpdateBtnStates;
end; end;
procedure TStemLeafFrm.UpdateBtnStates; procedure TStemLeafForm.Reset;
var
i: integer;
begin
inherited;
VarList.Clear;
for i := 1 to NoVariables do
VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]);
SelectList.Clear;
UpdateBtnStates;
end;
procedure TStemLeafForm.SelectListDblClick(Sender: TObject);
var
index: Integer;
begin
index := Selectlist.ItemIndex;
if index > -1 then
begin
VarList.Items.Add(SelectList.Items[index]);
SelectList.Items.Delete(index);
UpdateBtnStates;
end;
end;
procedure TStemLeafForm.UpdateBtnStates;
var var
lSelected: Boolean; lSelected: Boolean;
i: Integer; i: Integer;
begin begin
inherited;
lSelected := false; lSelected := false;
for i := 0 to VarList.Items.Count-1 do for i := 0 to VarList.Items.Count-1 do
if VarList.Selected[i] then if VarList.Selected[i] then
@ -424,13 +405,25 @@ begin
OutBtn.Enabled := lSelected; OutBtn.Enabled := lSelected;
end; end;
procedure TStemLeafFrm.VarListSelectionChange(Sender: TObject; User: boolean);
procedure TStemLeafForm.VarListDblClick(Sender: TObject);
var
index: Integer;
begin
index := VarList.ItemIndex;
if index > -1 then
begin
SelectList.Items.Add(VarList.Items[index]);
VarList.Items.Delete(index);
UpdateBtnStates;
end;
end;
procedure TStemLeafForm.VarListSelectionChange(Sender: TObject; User: boolean);
begin begin
UpdateBtnStates; UpdateBtnStates;
end; end;
initialization
{$I stemleafunit.lrs}
end. end.

View File

@ -2086,9 +2086,9 @@ end;
// Menu "Analysis" > "Descriptive" > "Stem and Leaf Plot" // Menu "Analysis" > "Descriptive" > "Stem and Leaf Plot"
procedure TOS3MainFrm.mnuAnalysisDescr_StemLeafClick(Sender: TObject); procedure TOS3MainFrm.mnuAnalysisDescr_StemLeafClick(Sender: TObject);
begin begin
if StemLeafFrm = nil then if StemLeafForm = nil then
Application.CreateForm(TStemLeafFrm, StemLeafFrm); Application.CreateForm(TStemLeafForm, StemLeafForm);
StemLeafFrm.Show; StemLeafForm.Show;
end; end;
// Menu "Analysis" > "Descriptive" > "3-D Variable Rotation" // Menu "Analysis" > "Descriptive" > "3-D Variable Rotation"

View File

@ -72,6 +72,7 @@ end;
procedure TBasicStatsParamsForm.Activate; procedure TBasicStatsParamsForm.Activate;
var var
w: Integer; w: Integer;
topSpacing, bottomSpacing: Integer;
begin begin
if FAutoSized then if FAutoSized then
exit; exit;
@ -84,7 +85,10 @@ begin
AdjustConstraints; AdjustConstraints;
Constraints.MinHeight := ParamsPanel.Constraints.MinHeight + ParamsPanel.BorderSpacing.Around*2; topSpacing := max(ParamsPanel.BorderSpacing.Top, ParamsPanel.BorderSpacing.Around);
bottomSpacing := max(ParamsPanel.BorderSpacing.Bottom, ParamsPanel.BorderSpacing.Around);
Constraints.MinHeight := ParamsPanel.Constraints.MinHeight + topSpacing + bottomSpacing;
Constraints.MinWidth := ParamsPanel.Constraints.MinWidth + 300; Constraints.MinWidth := ParamsPanel.Constraints.MinWidth + 300;
if Width < Constraints.MinWidth then Width := 1; // enforce constraints if Width < Constraints.MinWidth then Width := 1; // enforce constraints

View File

@ -43,9 +43,9 @@ begin
FReportFrame.Parent := Self; FReportFrame.Parent := Self;
FReportFrame.Align := alClient; FReportFrame.Align := alClient;
FReportFrame.BorderSpacing.Left := 4; FReportFrame.BorderSpacing.Left := 4;
FReportFrame.BorderSpacing.Top := 8; FReportFrame.BorderSpacing.Top := 4;
FReportFrame.BorderSpacing.Bottom := 8; FReportFrame.BorderSpacing.Bottom := 4;
FReportFrame.BorderSpacing.Right := 8; FReportFrame.BorderSpacing.Right := 4;
InitToolbar(FReportFrame.ReportToolbar, tpRight); InitToolbar(FReportFrame.ReportToolbar, tpRight);