W Stata 11, funkcja rowmedian pozwala na obliczanie median rzędów bezpośrednio za pomocą egen.
Jak obliczyć mediany rzędów?
Tytuł | Obliczanie median rzędów | |
Autor | Nicholas J. Cox, Durham University |
Obliczanie median w oprogramowaniu statystycznym, takim jak Stata, powinno być łatwe i zwykle jest. Kiedy chcemy uzyskać medianę rzędową – medianę w obrębie obserwacji na kilku zmiennych tego samego rodzaju – okazuje się to trudniejsze.
Problem ten wart jest omówienia, nie tylko dlatego, że pojawia się w praktyce. Stanowi on również mały przykład różnych części Staty w grze.
Podsumowując podstawy: jeśli chcesz medianę zmiennej, możesz sortować na tej zmiennej i wybrać medianę samodzielnie. Pewna ostrożność jest potrzebna, gdy interesuje nas tylko część obserwacji lub gdy brakuje wartości. Zazwyczaj użytkownicy uruchamiają podsumowanie, które zajmuje się wszystkimi tego typu sprawami i identyfikuje medianę w wynikach. Jest ona wtedy pozostawiana w pamięci natychmiast jako r(p50).
Jeśli zamiast tego chcesz umieścić medianę w zmiennej, możesz użyć egen, median(). Ma to największy sens, gdy twoje dane są podzielone na grupy i chcesz, aby mediana każdej grupy została zapisana do późniejszego wykorzystania. Stąd użyłbyś egen, median() razem z by:.
Kiedy masz kilka zmiennych tego samego rodzaju, czasami jest łatwa odpowiedź. Jeśli te zmienne są naprawdę danymi panelowymi lub podłużnymi, powinieneś przekształcić długie i pracować z inną strukturą danych. Życie będzie o wiele łatwiejsze w ten sposób, nie tylko dla median rzędów, które są teraz tylko medianami panelowymi, ale także dla prawie wszystkich rodzajów analiz, które możesz chcieć zrobić z takimi danymi.
Jeśli wiesz, że wartości twoich zmiennych rzędowych są w porządku liczbowym, tak że na przykład y1 jest zawsze mniejszy lub równy y2, który z kolei jest mniejszy lub równy y3, i tak dalej, wtedy mediana może być obliczona bezpośrednio jako jedna ze zmiennych lub średnia dwóch zmiennych, w zależności od tego, czy liczba zmiennych jest nieparzysta czy parzysta. Ale to byłoby zepsute przez jakiekolwiek brakujące wartości.
Możesz dostać się do tej sytuacji zmiennych wiersza w kolejności numerycznej za pomocą rowsort z SSC (wymaga Stata 8; działa tylko z wartościami całkowitymi) lub sortrows z SSC (wymaga Stata 9).
Następnie przychodzą sytuacje, gdy masz kilka zmiennych (dwie, trzy lub cztery), nad którymi chcesz wziąć medianę wiersza – i znowu żadne wartości nie są brakujące. Mediana dwóch zmiennych jest taka sama jak ich średnia, więc ten pierwszy przypadek jest łatwy:
. gen median = (y1 + y2) / 2
Mniej znana sztuczka dla trzech zmiennych również upraszcza rozwiązanie problemu:
. gen median = y1 + y2 + y3 - min(y1, y2, y3) - max(y1, y2, y3)
Słownie: oblicz sumę wierszy; następnie odejmij minimum i maksimum. To, co pozostanie, musi być medianą.
Teraz sztuczka dla czterech zmiennych jest natychmiastowa:
. gen median = (y1 + y2 + y3 + y4 - /// min(y1, y2, y3, y4) - max(y1, y2, y3, y4)) / 2
In words: work out the row sum; then subtract the minimum and the maximum. Co pozostaje jest suma dwóch wewnętrznych wartości, a połowa daje medianę.
Proste sztuczki dla pięciu lub więcej zmiennych, w ogóle, nie są w dowodach.
Niektóre myśli pokazuje, że krawaty nie stanowią problemu dla żadnej z tych sztuczek. Bardziej kłopotliwe jest założenie, że nie brakuje żadnych wartości. Istnieje pewien zakres dla ratowania problemów z brakującymi wartościami. Możesz obliczyć liczbę brakujących wartości z
. egen nmissing = rowmiss(varlist)
, ale dla kilku zmiennych, liczenie brakujących zmiennych w locie jest równie proste.
Z dowolnymi brakującymi zmiennymi, mediana dwóch może być uratowana przez
. gen median = (y1 + y2) / 2 . replace median = max(y1, y2) if median == .
Ta sekwencja poleceń wykorzystuje fakt, że max(y1, y2) jest nonmissing zawsze, gdy jedna z wartości jest. Jeśli brakuje obu wartości, to tak naprawdę nic nie tracimy, ponieważ niektóre braki są po prostu nadpisywane przez braki. Mógłbyś napisać min(y1, y2) jeśli to sprawiłoby, że czułbyś się bardziej komfortowo. (Dlaczego wynik jest taki sam?)
Podobnie, mediana trzech może być uratowana.
. gen median = y1 + y2 + y3 - min(y1, y2, y3) - max(y1, y2, y3)
Jeśli brakuje y1, y2, i y3, to już masz jedyną możliwą odpowiedź: brak. Sytuacje, które należy naprawić, to brak tylko jednej zmiennej oraz brak dwóch zmiennych w każdej obserwacji.
. replace median = max(y1, y2, y3) if (missing(y1) + missing(y2) + missing(y3)) == 2
Jeśli brakuje dwóch zmiennych, to możemy uzyskać drugą z max() i jest to automatycznie mediana.
. 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
Jeśli brakuje jednej zmiennej, to średnia z dwóch pozostałych daje medianę. Upewniamy się, że brakujące zmienne są ignorowane w sumie przez użycie 0 zamiast nich. Gdybyśmy wiedzieli, że wszystkie zmienne powinny być dodatnie (lub zerowe), wtedy moglibyśmy użyć wyrażeń takich jak max(y1, 0) zamiast wyrażeń takich jak cond(missing(y1), 0, y1), a gdybyśmy wiedzieli, że wszystkie zmienne powinny być ujemne (lub zerowe), moglibyśmy użyć min(y1, 0) zamiast. Dalej, można zrobić to samo z egen:
. egen rowsum = rowsum(y1 y2 y3). replace median = rowsum / 2 ///if (missing(y1) + missing(y2) + missing(y3)) == 1
Oczywiście, chociaż dotychczasowy kod ma pewną wartość ciekawostki, pokazując, że nie zawsze trzeba sortować, aby uzyskać mediany rzędów, naprawdę potrzebujemy programu ucieleśniającego bardziej systematyczne podejście.
Jednakże, nie ma oficjalnej funkcji egen dla median rzędów. Jeśli poszukasz funkcji dostarczonych przez społeczność i przyjrzysz się im uważnie, możesz zacząć widzieć dlaczego. W istocie, dwa podejścia były możliwe przed Stata 9.
Pierwsze, zaimplementowane w egen, rmed() z STB-57 (wymagana Stata 5), polega na zapętleniu obserwacji, skopiowaniu wartości do zmiennej, a następnie uzyskaniu mediany. Niestety, to podejście zakłada, że liczba zmiennych nie jest większa niż liczba obserwacji. Zazwyczaj jest to prawdą, ale nie zawsze. Co ważniejsze, to podejście może być naprawdę powolne.
Drugie, zaimplementowane w egen, rmedf() z SSC (wymagana Stata 6), polega na restrukturyzacji zbioru danych w locie, obliczeniu mediany, a następnie ponownej restrukturyzacji. Prawdopodobnie, restrukturyzacja zbioru danych nie jest czymś, co powinno być robione w środku funkcji egen, ale w każdym razie to podejście mogłoby łatwo zawieść, gdyby nie było wystarczająco dużo pamięci.
Ze Stata 9, jednakże, przychodzi bardziej pozytywna możliwość: użycie Mata. Pakiet egenmore na SSC zawiera egen, rowmedian(). Jest ona znacznie szybsza niż poprzednie funkcje egen – mimo że podstawowa pętla jest nadal pętlą nad obserwacjami – i wymaga niewiele dodatkowej pamięci. Oto kod:
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