In Stata 11 kunt u met de functie rowmedian direct rij-medianen berekenen met egen.
Hoe bereken ik rij-medianen?
Titel | Berekenen van rij-medianen | |
Auteur | Nicholas J. Cox, Durham University |
Het berekenen van medianen in statistische software zoals Stata zou eenvoudig moeten zijn, en dat is het meestal ook. Wanneer je een rij-mediaan wilt – een mediaan binnen waarnemingen over meerdere variabelen van dezelfde soort – blijkt dat lastiger.
Dit probleem is het bespreken waard, niet alleen omdat het zich in de praktijk voordoet. Het geeft ook een klein voorbeeld van verschillende delen van Stata in het spel.
Om de basis te recapituleren: als u een mediaan van een variabele wilt, zou u op die variabele kunnen sorteren en zelf de mediaan eruit pikken. Enige voorzichtigheid is geboden wanneer je slechts in een deel van de waarnemingen geïnteresseerd bent of wanneer er sprake is van ontbrekende waarden. Meestal starten gebruikers summarize, detail, dat al dit soort zaken regelt, en identificeren de mediaan binnen de resultaten. Deze wordt dan onmiddellijk in het geheugen achtergelaten als r(p50).
Als u in plaats daarvan de mediaan in een variabele wilt stoppen, kunt u egen, median() gebruiken. Dit is het meest zinvol wanneer uw gegevens zijn onderverdeeld in groepen en u wilt dat de mediaan van elke groep wordt vastgelegd voor later gebruik. Vandaar dat je egen, mediaan() zou gebruiken samen met by:.
Wanneer je een stel variabelen van dezelfde soort hebt, is er soms een eenvoudig antwoord. Als die variabelen echt panel- of longitudinale gegevens zijn, moet je ze een andere vorm geven en met een andere gegevensstructuur werken. Het leven zal dan veel gemakkelijker zijn, niet alleen voor de rij-medianen, die nu gewoon panel-medianen zijn, maar ook voor bijna alle soorten analyses die je met dergelijke gegevens zou willen doen.
Als je weet dat de waarden van je rijvariabelen in numerieke volgorde staan, zodat bijvoorbeeld y1 altijd kleiner of gelijk is aan y2, die op zijn beurt kleiner of gelijk is aan y3, enzovoort, dan kan de mediaan direct worden berekend als ofwel een van de variabelen ofwel het gemiddelde van twee van de variabelen, afhankelijk van het feit of het aantal variabelen oneven of even is. Maar dat zou worden verknoeid door ontbrekende waarden.
U kunt die situatie van rijvariabelen in numerieke volgorde bereiken door rowsort van SSC te gebruiken (vereist Stata 8; werkt alleen met gehele waarden) of sortrows van SSC (vereist Stata 9).
Daarna komen situaties waarin u weinig variabelen hebt (twee, drie of vier) waarover u de rij-mediaan wilt nemen – en weer ontbreken er geen waarden. De mediaan van twee variabelen is gelijk aan hun gemiddelde, dus dat eerste geval is gemakkelijk:
. gen median = (y1 + y2) / 2
Een minder bekende truc voor drie variabelen maakt het oplossen van het probleem ook eenvoudig:
. gen median = y1 + y2 + y3 - min(y1, y2, y3) - max(y1, y2, y3)
In woorden: bereken de som van de rijen; trek dan het minimum en het maximum af. Wat overblijft moet de mediaan zijn.
Nu volgt onmiddellijk een truc voor vier variabelen:
. gen median = (y1 + y2 + y3 + y4 - /// min(y1, y2, y3, y4) - max(y1, y2, y3, y4)) / 2
In woorden: bereken de som van de rijen; trek er dan het minimum en het maximum van af. Wat overblijft is de som van de twee binnenste waarden, en halveren geeft de mediaan.
Eenvoudige trucs voor vijf of meer variabelen zijn over het algemeen niet voorhanden.
Enige overdenking leert dat een band geen enkel probleem vormt voor een van deze trucs. De lastiger aanname is dat er geen waarden ontbreken. Er is enige mogelijkheid om problemen met ontbrekende waarden te redden. U kunt het aantal ontbrekende variabelen berekenen uit
. egen nmissing = rowmiss(varlist)
, maar voor een paar variabelen is het tellen van ontbrekende variabelen on the fly net zo gemakkelijk.
Met alle ontbrekende variabelen kan de mediaan van twee worden geborgen door
. gen median = (y1 + y2) / 2 . replace median = max(y1, y2) if median == .
Deze opdrachtreeks maakt gebruik van het feit dat max(y1, y2) niet-ontbreekt wanneer een van de waarden dat wel is. Als beide waarden ontbreken, verliezen we niet echt, aangezien ontbrekende waarden gewoon overschreven worden door ontbrekende waarden. Je zou min(y1, y2) kunnen schrijven als je je daar prettiger bij voelt. (Waarom is het resultaat hetzelfde?)
Evenzo kan de mediaan van drie worden gered.
. gen median = y1 + y2 + y3 - min(y1, y2, y3) - max(y1, y2, y3)
Als y1, y2, en y3 allemaal ontbreken, heb je al het enige mogelijke antwoord: ontbreken. De op te lossen situaties zijn dat slechts één variabele ontbreekt en dat in elke waarneming twee variabelen ontbreken.
. replace median = max(y1, y2, y3) if (missing(y1) + missing(y2) + missing(y3)) == 2
Als twee variabelen ontbreken, kunnen we de andere uit max() halen en is dat automatisch de mediaan.
. 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
Als één variabele ontbreekt, geeft het gemiddelde van de andere twee de mediaan. We zorgen ervoor dat ontbrekende variabelen in de som worden genegeerd door in plaats daarvan 0 te gebruiken. Als we wisten dat alle variabelen positief (of nul) moeten zijn, dan zou je termen als max(y1, 0) kunnen gebruiken in plaats van termen als cond(missing(y1), 0, y1), en als je wist dat alle variabelen negatief (of nul) moeten zijn, dan zou je in plaats daarvan min(y1, 0) kunnen gebruiken. Verder zou je hetzelfde kunnen doen met egen:
. egen rowsum = rowsum(y1 y2 y3). replace median = rowsum / 2 ///if (missing(y1) + missing(y2) + missing(y3)) == 1
Het is duidelijk dat, hoewel de code tot nu toe enige curiositeitswaarde heeft omdat het laat zien dat je niet altijd hoeft te sorteren om rij-medianen te krijgen, we echt een programma nodig hebben dat een meer systematische aanpak belichaamt.
Er is echter geen officiële egen functie voor rij-medianen. Als je op zoek gaat naar door de gemeenschap bijgedragen functies en ze zorgvuldig bekijkt, kun je beginnen te begrijpen waarom. In wezen waren er twee benaderingen mogelijk vóór Stata 9.
De eerste, geïmplementeerd in egen, rmed() van STB-57 (Stata 5 vereist), is om lussen over observaties te maken, waarden in een variabele te kopiëren en vervolgens de mediaan te krijgen. Helaas gaat deze aanpak ervan uit dat het aantal betrokken variabelen niet groter is dan het aantal waarnemingen. Dat is meestal, maar niet noodzakelijk, het geval. Belangrijker is dat deze aanpak inderdaad traag kan zijn.
De tweede, geïmplementeerd in egen, rmedf() van SSC (Stata 6 vereist), is om de dataset on the fly te herstructureren, de medianen te berekenen, en dan terug te herstructureren. Ongetwijfeld is het herstructureren van een dataset niet iets dat gedaan zou moeten worden in het midden van een egen functie, maar in ieder geval zou deze aanpak gemakkelijk kunnen mislukken als er niet genoeg geheugen beschikbaar zou zijn.
Met Stata 9 komt er echter een positievere mogelijkheid: het gebruik van Mata. Het pakket egenmore op SSC bevat egen, rowmedian(). Het is veel sneller dan eerdere egen functies – ook al is de basis lus nog steeds een lus over observaties – en het vereist weinig extra geheugen. Hier is de 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