In Stata 11 können Sie mit der Funktion rowmedian die Zeilenmediane direkt mit egen berechnen.
Wie berechne ich Zeilenmediane?
Titel | Berechnen von Zeilenmedianen | |
Autor | Nicholas J. Cox, Durham University |
Das Berechnen von Medianen in statistischer Software wie Stata sollte einfach sein, und das ist es normalerweise auch. Wenn man einen Zeilenmedian sucht – einen Median innerhalb von Beobachtungen über mehrere gleichartige Variablen – wird es schwieriger.
Dieses Problem ist eine Diskussion wert, nicht nur weil es in der Praxis auftritt. Es liefert auch ein kleines Beispiel dafür, wie verschiedene Teile von Stata im Spiel sind.
Um die Grundlagen zu rekapitulieren: Wenn Sie den Median einer Variablen wollen, können Sie nach dieser Variable sortieren und den Median selbst heraussuchen. Etwas Vorsicht ist immer dann geboten, wenn man nur an einem Teil der Beobachtungen interessiert ist oder wenn es fehlende Werte gibt. Meistens rufen die Benutzer summarize, detail auf, das sich um all diese Dinge kümmert und den Median innerhalb der Ergebnisse ermittelt. Er wird dann sofort als r(p50) im Speicher belassen.
Wenn Sie stattdessen den Median in eine Variable setzen wollen, können Sie egen, median() verwenden. Dies ist vor allem dann sinnvoll, wenn die Daten in Gruppen unterteilt sind und der Median jeder Gruppe zur späteren Verwendung gespeichert werden soll. Daher würden Sie egen, median() zusammen mit by:.
Wenn Sie eine Reihe von Variablen der gleichen Art haben, gibt es manchmal eine einfache Antwort. Wenn es sich bei diesen Variablen wirklich um Panel- oder Längsschnittdaten handelt, sollten Sie Long umgestalten und mit einer anderen Datenstruktur arbeiten. Auf diese Weise wird das Leben viel einfacher, nicht nur für Zeilenmediane, die jetzt nur noch Panel-Mediane sind, sondern auch für fast alle Arten von Analysen, die Sie mit solchen Daten durchführen möchten.
Wenn Sie wissen, dass die Werte Ihrer Zeilenvariablen in numerischer Reihenfolge sind, so dass zum Beispiel y1 immer kleiner oder gleich y2 ist, das wiederum kleiner oder gleich y3 ist, und so weiter, dann kann der Median direkt entweder als eine der Variablen oder als der Mittelwert von zwei der Variablen berechnet werden, je nachdem, ob die Anzahl der Variablen ungerade oder gerade ist. Aber das würde durch fehlende Werte durcheinander gebracht werden.
Sie können zu dieser Situation von Zeilenvariablen in numerischer Reihenfolge gelangen, indem Sie rowsort aus SSC (erfordert Stata 8; funktioniert nur mit ganzzahligen Werten) oder sortrows aus SSC (erfordert Stata 9) verwenden.
Als Nächstes kommen Situationen, in denen Sie nur wenige Variablen (zwei, drei oder vier) haben, über die Sie den Zeilenmedian nehmen wollen – und wieder fehlen keine Werte. Der Median von zwei Variablen ist dasselbe wie ihr Mittelwert, so dass dieser erste Fall einfach ist:
. gen median = (y1 + y2) / 2
Ein weniger bekannter Trick für drei Variablen macht die Lösung des Problems ebenfalls einfach:
. gen median = y1 + y2 + y3 - min(y1, y2, y3) - max(y1, y2, y3)
In Worten: Berechne die Zeilensumme; ziehe dann das Minimum und das Maximum ab. Was übrig bleibt, muss der Median sein.
Nun ist ein Trick für vier Variablen sofort ersichtlich:
. gen median = (y1 + y2 + y3 + y4 - /// min(y1, y2, y3, y4) - max(y1, y2, y3, y4)) / 2
In Worten: Berechne die Zeilensumme; dann subtrahiere das Minimum und das Maximum. Was übrig bleibt, ist die Summe der beiden inneren Werte, und die Halbierung ergibt den Median.
Einfache Tricks für fünf oder mehr Variablen sind im Allgemeinen nicht zu finden.
Einige Überlegungen zeigen, dass Unentschiedenheit für keinen dieser Tricks ein Problem darstellt. Die schwierigere Annahme ist, dass keine Werte fehlen. Es gibt einige Möglichkeiten, die Probleme mit fehlenden Werten zu lösen. Man kann die Anzahl der fehlenden Werte aus
. egen nmissing = rowmiss(varlist)
berechnen, aber bei einigen wenigen Variablen ist es genauso einfach, die fehlenden Variablen spontan zu zählen.
Bei allen fehlenden Variablen kann der Median von zwei durch
. gen median = (y1 + y2) / 2 . replace median = max(y1, y2) if median == .
gerettet werden. Wenn beide Werte fehlen, ist das kein wirklicher Nachteil, da einige fehlende Werte einfach durch fehlende Werte überschrieben werden. Sie könnten auch min(y1, y2) schreiben, wenn Ihnen das lieber ist. (Warum ist das Ergebnis dasselbe?)
Auf ähnliche Weise kann der Median von drei Werten gerettet werden.
. gen median = y1 + y2 + y3 - min(y1, y2, y3) - max(y1, y2, y3)
Wenn y1, y2 und y3 alle fehlen, haben Sie bereits die einzig mögliche Antwort: fehlen. Die Situationen, die zu beheben sind, sind, dass nur eine Variable fehlt und dass zwei Variablen in jeder Beobachtung fehlen.
. replace median = max(y1, y2, y3) if (missing(y1) + missing(y2) + missing(y3)) == 2
Wenn zwei Variablen fehlen, dann können wir die andere aus max() erhalten und sie ist automatisch der Median.
. replace median = ( /// cond(missing(y1), 0, y1) + /// cond(missing(y2), 0, y2) + /// cond(missing(y3), 0, y3) ) / 2 /// if (missing(y1) + missing(y2) + missing(y3)) == 1
Wenn eine Variable fehlt, dann ergibt der Mittelwert der beiden anderen den Median. Wir stellen sicher, dass fehlende Werte in der Summe ignoriert werden, indem wir stattdessen 0 verwenden. Wenn man wüsste, dass alle Variablen positiv (oder Null) sein sollten, könnte man Begriffe wie max(y1, 0) statt Begriffe wie cond(missing(y1), 0, y1) verwenden, und wenn man wüsste, dass alle Variablen negativ (oder Null) sein sollten, könnte man stattdessen min(y1, 0) verwenden. Außerdem könnte man dasselbe mit egen machen:
. egen rowsum = rowsum(y1 y2 y3). replace median = rowsum / 2 ///if (missing(y1) + missing(y2) + missing(y3)) == 1
Obwohl der bisherige Code einen gewissen Kuriositätswert hat, indem er zeigt, dass man nicht immer sortieren muss, um Zeilenmediane zu erhalten, brauchen wir wirklich ein Programm, das einen systematischeren Ansatz verkörpert.
Allerdings gibt es keine offizielle egen-Funktion für Zeilenmediane. Wenn man sich die von der Gemeinschaft zur Verfügung gestellten Funktionen genau ansieht, wird klar, warum. Vor Stata 9 waren im Wesentlichen zwei Ansätze möglich.
Der erste, in egen implementierte, rmed() aus STB-57 (Stata 5 erforderlich), besteht darin, eine Schleife über die Beobachtungen zu ziehen, die Werte in eine Variable zu kopieren und dann den Median zu ermitteln. Leider setzt dieser Ansatz voraus, dass die Anzahl der betroffenen Variablen nicht größer ist als die Anzahl der Beobachtungen. Das ist in der Regel, aber nicht unbedingt der Fall. Noch wichtiger ist, dass dieser Ansatz in der Tat langsam sein kann.
Der zweite, in egen implementierte Ansatz, rmedf() von SSC (Stata 6 erforderlich), besteht darin, den Datensatz im laufenden Betrieb umzustrukturieren, Mediane zu berechnen und dann wieder umzustrukturieren. Man kann argumentieren, dass die Umstrukturierung eines Datensatzes nicht mitten in einer egen-Funktion durchgeführt werden sollte, aber in jedem Fall könnte dieser Ansatz leicht scheitern, wenn nicht genügend Speicher zur Verfügung steht.
Mit Stata 9 gibt es jedoch eine positivere Möglichkeit: die Verwendung von Mata. Das Paket egenmore auf SSC enthält egen, rowmedian(). Sie ist viel schneller als frühere egen-Funktionen – auch wenn die grundlegende Schleife immer noch eine Schleife über Beobachtungen ist – und benötigt wenig zusätzlichen Speicher. Hier ist der Code:
program _growmedian version 9 gettoken type 0 : 0 gettoken h 0 : 0 gettoken eqs 0 : 0 syntax varlist(numeric) if `"`by'"' != "" { _egennoby rowmedian() `"`by'"' /* NOTREACHED */ } marksample touse, novarlist quietly { mata : row_median("`varlist'", "`touse'", "`h'", "`type'") } end mata : void row_median(string scalar varnames, string scalar tousename, string scalar medianname, string scalar type) { real matrix y real colvector median, row real scalar n st_view(y, ., tokens(varnames), tousename) median = J(rows(y), 1, .) for(i = 1; i