Programmierung

Ab durch die Mitte!

Zum Analysieren von Werten können verschiedene Indikatoren verwendet werden. Die wohl gängigsten sind Maximum, Minimum und der Durchschnittswert. Aber auch der Median spielt oft eine Rolle. In folgendem Artikel möchte ich Ihnen erläutern, was der Median ist und wie er in CONZEPT 16 berechnet werden kann.


Was ist der Median?

Unter dem Median wird der Mittelwert einer sortierten Reihenfolge verstanden. Der Median ist immer der Wert, der in der Mitte dieser Reihenfolge liegt. Zum Beispiel entspricht bei einer Aneinanderreihung von sieben Werten der Median dem vierten Wert.
Bei einer ungeraden Anzahl von Werten liegt der Median genau in der Mitte, allerdings müssen diese Werte nach der Größe sortiert sein.

Bei einer geraden Anzahl von Werten wird der Median etwas anders berechnet. Es wird zuerst der Unter- und Obermedian gesucht. Das sind die beiden Werte, die in der Mitte liegen und die Grenze nach unten und oben darstellen. Aus diesen kann der eigentliche Median ermittelt werden. Dazu wird der Durchschnitt aus dem Unter- und Obermedian berechnet. Bei acht Werten zum Beispiel, wird der vierte und fünfte Wert addiert und durch zwei geteilt. Das Resultat ist dann der Median.

Median vs. Durchschnitt

Im Gegensatz zum Median werden beim Durchschnittswert alle Werte zusammengerechnet und durch die Anzahl der Werte dividiert. Dieses Verfahren hat den Nachteil, dass der Durchschnittswert sehr stark von den einzelnen Werten beeinflusst werden kann.
Dies möchte ich an einem kleinen Beispiel veranschaulichen.

Wir haben folgende Werte in einer Tabelle:

  • 75
  • 80
  • 83
  • 90
  • 96
  • 105
  • 135
  • 165
  • 200
Verhältnisdarstellung von Median und Durchschnitt

Der Durchschnittswert aus diesen Werten beträgt 114.33. Daraus könnten wir uns erschließen, dass der Wert 114.33 ein gewöhnlicher Wert in der Tabelle ist. Dies wäre aber falsch. Der Durchschnitt wurde durch die letzten 3 Werte stark verändert.

Der Median in diesem Beispiel ist die 96, da diese genau in der Mitte liegt. Laut ihm könnten wir davon ausgehen, dass ein gewöhnliches Feld ca. den Wert 96 hat. Der Median teilt die Werte in zwei Hälften, sodass es eine gleiche Anzahl von Werten gibt, die größer und kleiner als er sind. Der Median ist unempfindlich gegen Ausreißer.

Der Median in CONZEPT 16

Wäre es nicht interessant, den Median von einem bestimmten Feld aus einer Tabelle zu ermitteln? Mit Hilfe der unten zum Download bereitgestellten Prozedur Fnc.Aggegrate ist das möglich. So können Sie den kleinsten, den größten, den Durchschnittswert und den Median ganz einfach ermitteln. Wir haben das Feld ffSlsSolds vom Typ float. In diesem Feld steht der Umsatz an einem bestimmten Datum. Dieses Feld sortieren wir mit Hilfe einer Selektion und erfassen dann, je nachdem welche Aggregationen ausgewählt wurden, den dazugehörigen Inhalt.

Für den Median sieht das Ganze beispielsweise so aus:

// Soll Median ermittelt werden
if (aAggregations & _Rec.AggMed != 0 and vCount > 0)
{
  // Medianposition ermitteln
  tMedPos # ((vCount - 1) / 2) + 1;
  // Median ermitteln
  if (
    // Ersten Datensatz lesen
    RecRead(aTblNo, tKeyOrSel, _RecFirst) = _rOK and
    // Medianposition = 1
    tMedPos = 1 or
    // Datensatz an Medianposition lesen
    RecRead(aTblNo, tKeyOrSel, _RecNext, 0, (tMedPos - 1)) = _rOK)
  {
    // Unterscheidung über Datentyp
    switch (tFldType)
    {
     // Datentyp = float
     case _TypeFloat   :
      {
        vMed # FldFloat(aTblNo, aSbrNo, aFldNo);
        // Wenn die Anzahl der Datensätze gerade ist und der nächste Datensatz gelesen werden konnte
        if (vCount % 2 = 0 and RecRead(aTblNo, tKeyOrSel, _RecNext) = _rOK)
          vMed # (vMed + FldFloat(aTblNo, aSbrNo, aFldNo)) / 2\f;
      }
      //...
    }
  }
}

Die Funktion Rec.Aggregate() hat folgende Signatur:

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Datensätze aggregieren                                    +
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

sub Rec.Aggregate
(
  aTblNo                : int;            // Tabellennummer
  aSbrNo                : int;            // Teildatensatznummer
  aFldNo                : int;            // Feldnummer
  aAggregations         : int;            // Aggregationen
                                          //   _Rec.AggMin - kleinster Wert
                                          //   _Rec.AggMax - größter Wert
                                          //   _Rec.AggAvg - Durchschnitt
                                          //   _Rec.AggSum - Summe
                                          //   _Rec.AggMed - Median
  aQuery                : alpha(4096);    // Abfrage (optional)
  var vCount            : int;            // Anzahl
  var vSum              : float;          // Summe
  var vMin              : float;          // kleinster Wert
  var vMax              : float;          // größter Wert
  var vAvg              : float;          // Durchschnitt
  var vMed              : float;          // Median
)
: int;                                    // Resultat
                                          // = _ErrOk (0) : Erfolg
                                          // < 0 : Fehler (Siehe SelDefQuery, SelStore und SelRun)

Je nachdem welche Aggregationen angegeben wurden, werden die dazugehörigen Werte an die mit var deklarierten Variablen zurückgegeben. Die Anzahl der aggregierten Werte wird immer ermittelt.

Die Funktion kann Felder der folgenden Typen aggregieren:

  • word
  • int
  • bigint
  • decimal
  • float
Beispiel

Der folgende Funktionsaufruf ermittelt den kleinsten, den größten und den Median-Wert des Umsatzes pro Tag innerhalb des ersten Quartals des Jahres 2013:

// Feld bestimmen
tField # 'ffSlsSold';

tResult # Rec.Aggregate(
  FldInfoByName(tField, _FileNumber),           // Tabellennummer
  FldInfoByName(tField, _SbrNumber),            // Teildatensatznummer
  FldInfoByName(tField, _FldNumber),            // Feldnummer
  _Rec.AggMin | _Rec.AggMax | _Rec.AggMed,      // Aggregationen
  'fdSlsDate between [01.01.2013, 31.03.2013]', // Abfrage
  var tCount,                                   // Anzahl
  var tSum,                                     // Summe
  var tMin,                                     // Kleinster Wert
  var tMax,                                     // Größter Wert
  var tAvg,                                     // Durchschnitt
  var tMed                                      // Median
);

In der oben zu sehenden Funktion, werden die Aggregationen _Rec.AggMin, _Rec.AggMax und _Rec.AggMed übergeben. Das bedeutet, dass der kleinste Wert, der größte Wert und der Median des Feldes ffSlsSold ermittelt werden sollen. Eine Kombination von allen Aggregationen zusammen ist ebenfalls möglich. Für das Erfassen der Datensatzanzahl wird keine Aggregation benötigt. Die Datensatzanzahl wird immer zurückgegeben.
Im Download finden Sie eine Datenbank inklusive Datensätze. Die Funktion Rec.Aggregate ist dort enthalten und kann nach Belieben angepasst werden.

Download

Zum downloaden hier klicken RecAggregate.zip (1.60 MB)
Sie müssen angemeldet sein, um die Datei herunterladen zu können.

Keine Kommentare

Kommentar abgeben