📄 ostat.c
字号:
LT_get_str( "%A", szTemp, 40 );
strVarName = szTemp;
// Get type of variable in row ii and column 2 of list control
strDB.Format( "%%A=ANOVA2Way!SelectedDataLCNTRL.V%d_2$", ii );
LT_execute( strDB );
LT_get_str( "%A", szTemp, 40 );
strVarType = szTemp;
// Save dataset and variable type names for output
str.Format( OSTAT_STR_TOKEN, OSTAT_SEPARATOR_CHAR, strVarType );
vDataNames[ ii - 1 ] = strVarName + str;
// Associate dataset name with variable type
if( strVarType.Compare( AN2_DEPENDENT_VAR ) == 0)
strDepVar = strVarName; // Dataset is the dependent variable
else
if( strVarType.Compare( AN2_FACTOR_A_VAR ) == 0 )
strFactAVar = strVarName; // Dataset is the Factor A classification variable
else
strFactBVar = strVarName; // Dataset is the Factor B classification variable
}
// Read in Dependent Variable and get number of data points
dsDATA_IN.Attach( strDepVar );
// Do not allow missing or masked values because the dependent variable is paired row wise with classification variables
if( DatasetHasNonNumericValues( dsDATA_IN ) )
{
strErrMsg.Format( AN2_DEPVAR_HAS_NONNUMERICS, strDepVar );
Type_ErrorMsg( strErrMsg );
return OSTAT_ABORT_NO_ERROR_MSG;
}
iSize = dsDATA_IN.GetSize();
vDEP_VAR.SetSize( iSize );
vDEP_VAR = dsDATA_IN;
dsDATA_IN.Detach();
// Read in Factor A dataset
bErr = cdDATA_IN.Attach( strFactAVar, CMT_NOMINAL ); // Use Categorical Data
if( !bErr )
return OSTAT_ABORT_NO_ERROR_MSG;
iSize = cdDATA_IN.GetSize();
vFACTOR_A.SetSize( iSize );
vFACTOR_A = cdDATA_IN;
vLEVELSA = (StringArray) cdDATA_IN.Map; // Get Categorical Data Map holding Factor A level names
cdDATA_IN.Detach();
// Read in Factor B dataset
bErr = cdDATA_IN.Attach( strFactBVar, CMT_NOMINAL ); // Use Categorical Data
if( !bErr )
return OSTAT_ABORT_NO_ERROR_MSG;
iSize = cdDATA_IN.GetSize();
vFACTOR_B.SetSize( iSize );
vFACTOR_B = cdDATA_IN;
vLEVELSB = (StringArray) cdDATA_IN.Map; // Get Categorical Data Map holding Factor B level names
cdDATA_IN.Detach();
}
nLevelsA = vLEVELSA.GetSize(); // Get number of levels for Factor A
nLevelsB = vLEVELSB.GetSize(); // Get number of levels for Factor B
iSize = vDEP_VAR.GetSize(); // Get final size of variables
// Count number of data values in each treatment combination group (Cell)
mValuesPerCell.SetSize( nLevelsA, nLevelsB );
iErr = osANOVA2Way_Count_Values_Per_Cell( vFACTOR_A, vFACTOR_B, mValuesPerCell, AN2_MIN_VALUES_PER_CELL, ii, jj );
// Terminate with error message if too few data values in treatment combination group (Cell)
if( iErr != OSTAT_NO_ERROR )
{
strErrMsg.Format( AN2_TOO_FEW_DATA_PTS_IN_CELL, vLEVELSA[ii], vLEVELSB[jj], AN2_MIN_VALUES_PER_CELL );
Type_ErrorMsg( strErrMsg );
return OSTAT_ABORT_NO_ERROR_MSG;
}
return OSTAT_NO_ERROR;
}
/**
Two-Way ANOVA function to count the number of data values in each treatment level combination. The counts are
stored in a matrix because there are two dimensions in a Two-Way ANOVA.
Example:
See the function osANOVA2Way_Get_Data above for a sample call.
Parameter:
v1=Input vector containing indices to Factor A levels identifying the first dimension of each cell address in matrix
v2=Input vector containing indices to Factor B levels identifying the second dimension of each cell address in matrix
mCount=Number of data points in each cell of matrix
iThreshold=Minimum number of data points required in each cell of matrix
iRow=Row index of first cell in matrix having fewer than iThreshold data points. Returns -1 if no such cell is found.
iCol=Column index of first cell in matrix having fewer than iThreshold data points. Returns -1 if no such cell is found.
Return:
Returns the matrix of cell counts, the index of the first cell having fewer than iThreshold data points, and the
number of cells having fewer than iThreshold data points or zero if no such cells are found.
*/
int osANOVA2Way_Count_Values_Per_Cell( vector<int> &v1, vector<int> &v2, matrix<int> &mCount, int iThreshold, int &iRow, int &iCol )
{
int ii, jj, iRet;
int n1, n2, nPts;
// Vectors should have same size
nPts = v1.GetSize();
if( nPts > v2.GetSize() )
nPts = v2.GetSize();
// Get the number of rows and columns in the matrix which is the same as the number of unique indices in each vector (v1 and v2)
n1 = mCount.GetNumRows();
n2 = mCount.GetNumCols();
// Initialize count matrix
mCount = 0;
// Initialize cell index and count of cells having fewer than iThreshold data points
iRet = OSTAT_NO_ERROR;
iRow = -1;
iCol = -1;
// Loop through all elements in vectors counting number
for( ii = 0; ii < nPts; ii++ )
{
mCount[ v1[ii] - 1 ][ v2[ii] - 1 ]++; // Increment cell count...levels are indexed from 1 whereas matices are indexed from 0
// so subtract 1 from indices stored in vectors
}
// Loop through all cells in matrix looking for cells where count is less than iThreshold
for( ii = 0; ii < n1; ii++ ) // For all ii rows in matrix...
{
for( jj = 0; jj < n2; jj++ ) // For all jj columns in matrix...
{
if( mCount[ii][jj] < iThreshold ) // If cell count is lower than threshold...
{
if( iRet == OSTAT_NO_ERROR ) // If first cell lower than iThreshold...
{
iRow = ii; // Set return address of cell
iCol = jj;
} // End first cell
iRet++; // Count number of cells less than iThreshold
} // End cell count lower than iThreshold
} // End all jj columns
} // End all ii rows
return iRet;
}
/**
Two-Way ANOVA function to add a string to a vector if the string is not already in the vector. The index
of the string in the vector is returned whether the string is found or added.
Example:
See the function osANOVA2Way_Get_Data above for a sample call.
Parameter:
strIn=String to search for and add if not found
vSTRINGS=Vector of strings to search
Return:
Returns the 0 based index of the string in the vector whether found or added.
*/
int osANOVA2Way_Add_String_to_Vector( string strIn, vector<string> &vSTRINGS )
{
int ii, iSize;
iSize = vSTRINGS.GetSize();
// Loop on all strings in vector
for( ii = 0; ii < iSize; ii++ )
{
if( strIn.Compare( vSTRINGS[ii] ) == 0 ) // If string is in vector break loop when ii < iSize
break;
}
// If string not in vector then add it
if( ii == iSize )
{
vSTRINGS.SetSize( iSize + 1 );
vSTRINGS[ii] = strIn;
}
return ii; // Return 0 based index of string in vector
}
/**
Two-Way ANOVA function used (at one point) to count the number of unique data values (Levels) in a dataset.
Example:
This function is not currently used by OSTAT but is left in until it can be moved to App_Utils.h for general use.
Parameter:
nPts=Number of data points in dataset
dsDATASET=Dataset whose unique values are counted
nCount=Output the number of unique data values in a data set
Return:
Returns the number of unique data values in a data set.
*/
int osANOVA2Way_Count_Unique_Values( int nPts, Dataset &dsDATASET, int &nCount )
{
int ii;
BOOL bErr;
// Make temporary copy of passed dataset
Dataset dsSortedDATA( dsDATASET );
// Sort temporary copy of dataset
bErr = Data_sort( &dsSortedDATA );
if( bErr == FALSE )
return OSTAT_DATA_SORT_ERROR2;
// Loop through dataset counting the number of unique values in the dataset
nCount = 1;
for( ii = 0; ii < nPts - 1; ii++ )
{
if( dsSortedDATA[ii] != dsSortedDATA[ii + 1] ) // If current value does not equal next value then...
nCount++; // increment count of unique vales in dataset
}
dsSortedDATA.Detach();
return OSTAT_NO_ERROR;
}
/**
Two-Way ANOVA function to compute the Two-Way ANOVA F table. The Origin Two-Way ANOVA dialog
box uses a linear regression approach in order to support unequal cell sizes (However, empty
cells are not supported). The reference for Origin's two-way analysis of variance is Applied
Linear Statistical Models, Neter J., Kutner M., Nachtsheim C., and Wasserman W. (1996), The
McGraw-Hill Companies, Inc., Boston, MA. See Section 22.2 for a discussion of how to use dummy
variables for testing both factor main effects and interaction effects. The Origin Two-Way ANOVA
dialog box also makes use of the NAG functions nag_dummy_vars (g04eac) to create the necessary
design matrices and nag_regsn_mult_linear (g02dac) to perform the linear regressions of the
design matrices. The results of the linear regressions are then used to construct the two-way
ANOVA table.
Example:
See the main Two-Way ANOVA function osANOVA2Way above for a sample call.
Parameters:
iInteractions=Flag indicating whether (1) or not (0) interaction effects are to be determined
vFACTOR_A=Vector containing integerized level indices (1 based) for Factor A
nLevelsA=The number of Factor A levels
vFACTOR_B=Vector containing integerized level indices (1 based) for Factor B
nLevelsB=The number of Factor D levels
vDEP_VAR=Vector containing dependent variable data values
nPts=Number of data values
arANOVA2_Table=A four element array of an ANOVA2_Row structure holding all computed F Table
values one element for each row of the ANOVA F table (A, B, A * B, and Error).
Return:
Returns a four element array of an ANOVA2_Row structure holding all computed F Table values
which has one element for each row in the ANOVA F table (A, B, A * B, and Error). Also returns
OSTAT_NO_ERROR on successful exit or an OSTAT error code on failure.
*/
int osANOVA2Way_Compute_ANOVA_Table( int iInteractions, vector<int> &vFACTOR_A, int nLevelsA, vector<int> &vFACTOR_B,
int nLevelsB, vector<double> &vDEP_VAR, int nPts, ANOVA2_Row *arANOVA2_Table )
{
int ii, iErr, iAxBDim, iXDim;
double dRss, dDf;
int ariLinRegrErr[4]; // Array to hold ANOVA Linear regression errors
int ariProbFErr[4]; // Array to hold ANOVA Prob F errors
NagError neErr;
NagError *pneFail = &neErr; // NAG error structure
// Compute dummy variables for Factor A for use in linear regressions
matrix<double> mX_FACT_A;
mX_FACT_A.SetSize( nPts, nLevelsA - 1 );
iErr = osANOVA2Way_Compute_Dummy_Vars( nPts, nLevelsA, vFACTOR_A, mX_FACT_A );
if( iErr != OSTAT_NO_ERROR )
return iErr;
// Compute dummy variables for Factor B for use in linear regressions
matrix<double> mX_FACT_B;
mX_FACT_B.SetSize( nPts, nLevelsB - 1 );
iErr = osANOVA2Way_Compute_Dummy_Vars( nPts, nLevelsB, vFACTOR_B, mX_FACT_B );
if( iErr != OSTAT_NO_ERROR )
return iErr;
matrix<double> mX_FACTs_AxB;
// Compute dummy variables for Factors A x B for use in linear regressions
if( iInteractions )
{
iAxBDim = ( nLevelsA - 1 ) * ( nLevelsB - 1 );
mX_FACTs_AxB.SetSize( nPts, iAxBDim );
iErr = osANOVA2Way_Compute_FACTsAxB_Dummy_Vars( nPts, nLevelsA, mX_FACT_A, nLevelsB, mX_FACT_B, mX_FACTs_AxB );
if( iErr != OSTAT_NO_ERROR )
return iErr;
}
else
iAxBDim = 0;
matrix<double> mX; // Main dummy variable matrix
// Element 0 is A source, element 1 is B source, element 2 is A * B source (interactions),
// and element 3 is Error source
// *** Perform linear regression with all dummy variables computing the residual sum ***
// *** of squares (dRss) and degrees of freedom (dDf) for the Error source (compute ***
// *** first as this is needed when computing other sources) ***
// Combine Factor A, Factor B, and (if needed) Interaction dummy variable matrices
iXDim = nLevelsA + nLevelsB + iAxBDim - 2;
mX.SetSize( nPts, iXDim );
osANOVA2Way_Copy_Matrix( nPts, nLevelsA - 1, mX_FACT_A, 0, mX ); // Copy Factor A dummy variables
osANOVA2Way_Copy_Matrix( nPts, nLevelsB - 1, mX_FACT_B, nLevelsA - 1, mX ); // Copy Factor B dummy variables
if( iInteractions ) // If Interactions are to be computed...
osANOVA2Way_Copy_Matrix( nPts, iAxBDim, mX_FACTs_AxB, nLevelsA + nLevelsB - 2, mX ); // Copy Interaction A * B dummy variables
// Perform linear regression for Error row
iErr = osANOVA2Way_Perform_Linear_Regression( nPts, iXDim, mX, vDEP_VAR, dRss, dDf );
ariLinRegrErr[3] = iErr;
// Compute Error row of Two-Way ANOVA table
arANOVA2_Table[3].dDF = dDf;
arANOVA2_Table[3].dSS = dRss;
arANOVA2_Table[3].dMS = arANOVA2_Table[3].dSS / arANOVA2_Table[3].dDF;
arANOVA2_Table[3].dF = NANUM;
arANOVA2_Table[3].dP = NANUM;
ariProbFErr[3] = NE_NOERROR;
// *** Perform linear regression with all but factor A dummy variables computing the residual sum ***
// *** of squares (dRss) and degrees of freedom (dDf) for the A source ***
// Combine Factor B and (if needed) Interaction dummy variable matrices
iXDim = nLevelsB + iAxBDim - 1;
mX.SetSize( nPts, iXDim );
osANOVA2Way_Copy_Matrix( nPts, nLevelsB - 1, mX_FACT_B, 0, mX ); // Copy Factor B dummy variables
if( iInteractions ) // If Interactions are to be computed...
osANOVA2Way_Copy_Matrix( nPts, iAxBDim, mX_FACTs_AxB, nLevelsB - 1, mX ); // Copy Interaction A * B dummy variables
// Perform linear regression for A row
iErr = osANOVA2Way_Perform_Linear_Regression( nPts, iXDim, mX, vDEP_VAR, dRss, dDf );
ariLinRegrErr[0] = iErr;
// Compute row A of Two-Way ANOVA table
arANOVA2_Table[0].dDF = dDf - arANOVA2_Table[3].dDF;
arANOVA2_Table[0].dSS = dRss - arANOVA2_Table[3].dSS;
arANOVA2_Table[0].dMS = arANOVA2_Table[0].dSS / arANOVA2_Table[0].dDF;
arANOVA2_Table[0].dF = arANOVA2_Table[0].dMS / arANOVA2_Table[3].dMS;
arANOVA2_Table[0].dP = 1 - nag_prob_f_dist( Nag_LowerTail, arANOVA2_Table[0].dF, arANOVA2_Table[0].dDF,
arANOVA2_Table[3].dDF, pneFail );
ariProbFErr[0] = pneFail->code;
// *** Perform linear regression with all but factor B dummy variables computing the residual sum ***
// *** of squares (dRss) and degrees of freedom (dDf) for the B source ***
// Combine Factor A and (if needed) Interaction dummy variable matrices
iXDim = nLevelsA + iAxBDim - 1;
mX.SetSize( nPts, iXDim );
osANOVA2Way_Copy_Matrix( nPts, nLevelsA - 1, mX_FACT_A, 0, mX ); // Copy Factor A dummy variables
if( iInteractions ) // If Interactions are to be computed...
osANOVA2Way_Copy_Matrix( nPts, iAxBDim, mX_FACTs_AxB, nLevelsA - 1, mX ); // Copy Interaction A * B dummy variables
// Perform linear regression for B ro
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -