Skip to content
Permalink
Browse files

Add calculation of number of null values to QgsStatisticalSummary

  • Loading branch information
nyalldawson committed May 16, 2016
1 parent 4dea723 commit 1c45b940a83b5ac256d4fc7241791aa55197f316
@@ -22,6 +22,7 @@ class QgsStatisticalSummary
enum Statistic
{
Count, //!< Count
CountMissing, //!< Number of missing (null) values
Sum, //!< Sum of values
Mean, //!< Mean of values
Median, //!< Median of values
@@ -79,15 +80,36 @@ class QgsStatisticalSummary
* @note finalize() must be called after adding the final value and before
* retrieving calculated statistics.
* @see calculate()
* @see addVariant()
* @see finalize()
* @note added in QGIS 2.16
*/
void addValue( double value );

/** Adds a single value to the statistics calculation. Calling this method
* allows values to be added to the calculation one at a time. For large
* quantities of values this may be more efficient then first adding all the
* values to a list and calling calculate().
* @param value variant containing to add. Non-numeric values are treated as null.
* @note call reset() before adding the first value using this method
* to clear the results from any previous calculations
* @note finalize() must be called after adding the final value and before
* retrieving calculated statistics.
* @see addValue()
* @see calculate()
* @see finalize()
* @note added in QGIS 2.16
*/
void addVariant( const QVariant& value );

/** Must be called after adding all values with addValues() and before retrieving
* any calculated statistics.
* @see addValue()
* @see addVariant()
* @note added in QGIS 2.16
*/
void finalize();

/** Returns the value of a specified statistic
* @param stat statistic to return
* @returns calculated value of statistic
@@ -39,6 +39,7 @@ QgsStatisticalSummary::~QgsStatisticalSummary()
void QgsStatisticalSummary::reset()
{
mCount = 0;
mMissing = 0;
mSum = 0;
mMean = 0;
mMedian = 0;
@@ -88,6 +89,21 @@ void QgsStatisticalSummary::addValue( double value )
mValues << value;
}

void QgsStatisticalSummary::addVariant( const QVariant& value )
{
bool convertOk = false;
if ( !value.isValid() || value.isNull() )
mMissing++;
else
{
double val = value.toDouble( &convertOk );
if ( convertOk )
addValue( val );
else
mMissing++;
}
}

void QgsStatisticalSummary::finalize()
{
if ( mCount == 0 )
@@ -214,6 +230,8 @@ double QgsStatisticalSummary::statistic( QgsStatisticalSummary::Statistic stat )
{
case Count:
return mCount;
case CountMissing:
return mMissing;
case Sum:
return mSum;
case Mean:
@@ -254,6 +272,8 @@ QString QgsStatisticalSummary::displayName( QgsStatisticalSummary::Statistic sta
{
case Count:
return QObject::tr( "Count" );
case CountMissing:
return QObject::tr( "Count (missing)" );
case Sum:
return QObject::tr( "Sum" );
case Mean:
@@ -17,6 +17,7 @@
#define QGSSTATISTICALSUMMARY_H

#include <QMap>
#include <QVariant>

/***************************************************************************
* This class is considered CRITICAL and any change MUST be accompanied with
@@ -44,6 +45,7 @@ class CORE_EXPORT QgsStatisticalSummary
enum Statistic
{
Count = 1, //!< Count
CountMissing = 32770, //!< Number of missing (null) values
Sum = 2, //!< Sum of values
Mean = 4, //!< Mean of values
Median = 8, //!< Median of values
@@ -58,7 +60,7 @@ class CORE_EXPORT QgsStatisticalSummary
FirstQuartile = 4096, //!< First quartile
ThirdQuartile = 8192, //!< Third quartile
InterQuartileRange = 16384, //!< Inter quartile range (IQR)
All = Count | Sum | Mean | Median | StDev | Max | Min | Range | Minority | Majority | Variety | FirstQuartile | ThirdQuartile | InterQuartileRange
All = Count | CountMissing | Sum | Mean | Median | StDev | Max | Min | Range | Minority | Majority | Variety | FirstQuartile | ThirdQuartile | InterQuartileRange
};
Q_DECLARE_FLAGS( Statistics, Statistic )

@@ -101,13 +103,33 @@ class CORE_EXPORT QgsStatisticalSummary
* @note finalize() must be called after adding the final value and before
* retrieving calculated statistics.
* @see calculate()
* @see addVariant()
* @see finalize()
* @note added in QGIS 2.16
*/
void addValue( double value );

/** Adds a single value to the statistics calculation. Calling this method
* allows values to be added to the calculation one at a time. For large
* quantities of values this may be more efficient then first adding all the
* values to a list and calling calculate().
* @param value variant containing to add. Non-numeric values are treated as null.
* @note call reset() before adding the first value using this method
* to clear the results from any previous calculations
* @note finalize() must be called after adding the final value and before
* retrieving calculated statistics.
* @see addValue()
* @see calculate()
* @see finalize()
* @note added in QGIS 2.16
*/
void addVariant( const QVariant& value );

/** Must be called after adding all values with addValues() and before retrieving
* any calculated statistics.
* @see addValue()
* @see addVariant()
* @note added in QGIS 2.16
*/
void finalize();

@@ -121,6 +143,10 @@ class CORE_EXPORT QgsStatisticalSummary
*/
int count() const { return mCount; }

/** Returns the number of missing (null) values
*/
int countMissing() const { return mMissing; }

/** Returns calculated sum of values
*/
double sum() const { return mSum; }
@@ -209,6 +235,7 @@ class CORE_EXPORT QgsStatisticalSummary
Statistics mStatistics;

int mCount;
int mMissing;
double mSum;
double mMean;
double mMedian;
@@ -35,6 +35,7 @@ class TestQgsStatisticSummary: public QObject
void individualStatCalculations_data();
void individualStatCalculations();
void maxMin();
void countMissing();

private:

@@ -225,6 +226,7 @@ void TestQgsStatisticSummary::individualStatCalculations_data()
QTest::newRow( "first_quartile" ) << ( int )QgsStatisticalSummary::FirstQuartile << 3.0;
QTest::newRow( "third_quartile" ) << ( int )QgsStatisticalSummary::ThirdQuartile << 5.0;
QTest::newRow( "iqr" ) << ( int )QgsStatisticalSummary::InterQuartileRange << 2.0;
QTest::newRow( "missing" ) << ( int )QgsStatisticalSummary::CountMissing << 0.0;
}

void TestQgsStatisticSummary::individualStatCalculations()
@@ -281,5 +283,21 @@ void TestQgsStatisticSummary::maxMin()
QCOMPARE( s.max(), -5.0 );
}

void TestQgsStatisticSummary::countMissing()
{
QgsStatisticalSummary s( QgsStatisticalSummary::All );
s.addVariant( 5 );
s.addVariant( 6 );
s.addVariant( QVariant() );
s.addVariant( 7 );
s.addVariant( QVariant( QVariant::Double ) );
s.addVariant( 9 );
s.addVariant( "Asdasdsad" );
s.finalize();

QCOMPARE( s.countMissing(), 3 );
QCOMPARE( s.statistic( QgsStatisticalSummary::CountMissing ), 3.0 );
}

QTEST_MAIN( TestQgsStatisticSummary )
#include "testqgsstatisticalsummary.moc"

0 comments on commit 1c45b94

Please sign in to comment.
You can’t perform that action at this time.