I Stata 11 giver funktionen rowmedian dig mulighed for at beregne rækkemedianer direkte med egen.
Hvordan beregner jeg rækkemedianer?
Titel | Beregning af rækkemedianer | |
Author | Nicholas J. Cox, Durham University |
Beregning af medianer i statistisk software som Stata burde være nemt, og det er det som regel også. Når man ønsker en rækkemedian – en median inden for observationer på tværs af flere variabler af samme art – viser det sig at være vanskeligere.
Dette problem er en diskussion værd, ikke kun fordi det opstår i praksis. Det giver også et lille eksempel på forskellige dele af Stata i spil.
For at opsummere det grundlæggende: Hvis du vil have en median for en variabel, kan du sortere på den pågældende variabel og selv vælge medianen ud. Der er behov for en vis forsigtighed, når du kun er interesseret i nogle af observationerne, eller når der er manglende værdier. For det meste fyrer brugerne summarize, detail af, som tager sig af alle sådanne ting, og identificerer medianen i resultaterne. Den efterlades derefter straks i hukommelsen som r(p50).
Hvis du i stedet ønsker at sætte medianen ind i en variabel, kan du bruge egen, median(). Dette giver mest mening, når dine data er opdelt i grupper, og du ønsker, at hver gruppes median skal registreres til senere brug. Derfor vil du bruge egen, median() sammen med by:.
Når du har en masse variabler af samme slags, er der nogle gange et nemt svar. Hvis disse variabler virkelig er panel- eller longitudinelle data, bør du omforme long og arbejde med en anden datastruktur. Livet bliver meget nemmere på den måde, ikke kun for rækkemedianer, som nu bare er panelmedianer, men også for næsten alle former for analyser du, der måtte ønske at lave med sådanne data.
Hvis du ved, at værdierne af dine rækkevariabler er i numerisk rækkefølge, således at f.eks. y1 altid er mindre end eller lig med y2, som igen er mindre end eller lig med y3 osv. så kan medianen beregnes direkte som enten en af variablerne eller som middelværdien af to af variablerne, alt efter om antallet af variabler er lige eller ulige. Men det ville blive ødelagt af eventuelle manglende værdier.
Du kan komme til den situation med rækkevariabler i numerisk rækkefølge ved at bruge rowsort fra SSC (kræver Stata 8; virker kun med heltalsværdier) eller sortrows fra SSC (kræver Stata 9).
Dernæst kommer situationer, hvor du har få variabler (to, tre eller fire), som du ønsker at tage rækkemedianen over – og igen mangler der ingen værdier. Medianen for to variabler er det samme som deres gennemsnit, så det første tilfælde er let:
. gen median = (y1 + y2) / 2
Et mindre kendt trick for tre variabler gør det også let at løse problemet:
. gen median = y1 + y2 + y3 - min(y1, y2, y3) - max(y1, y2, y3)
Med andre ord: udregn rækkesummen; træk derefter minimum og maksimum fra hinanden. Det, der er tilbage, må være medianen.
Nu er et trick for fire variabler umiddelbart tilgængeligt:
. gen median = (y1 + y2 + y3 + y4 - /// min(y1, y2, y3, y4) - max(y1, y2, y3, y4)) / 2
Med andre ord: beregn rækkesummen og træk derefter minimum og maksimum fra. Det, der er tilbage, er summen af de to indre værdier, og hvis man halverer den, får man medianen.
Simple tricks for fem eller flere variabler er generelt ikke til stede.
Lidt eftertanke viser, at slips ikke udgør noget problem for nogen af disse tricks. Den mere besværlige antagelse er, at der ikke mangler nogen værdier. Der er visse muligheder for at redde problemer med manglende værdier. Man kan beregne antallet af manglende fra
. egen nmissing = rowmiss(varlist)
, men for nogle få variabler er det lige så nemt at tælle manglende variabler i farten.
Med eventuelle manglende variabler kan medianen af to reddes ved at
. gen median = (y1 + y2) / 2 . replace median = max(y1, y2) if median == .
Denne kommandosekvens udnytter det faktum, at max(y1, y2) er ikke-manglende, når en af værdierne er det. Hvis begge værdier mangler, taber vi ikke rigtig noget, da nogle manglende værdier bare overskrives af manglende værdier. Du kunne skrive min(y1, y2), hvis det var mere behageligt for dig. (Hvorfor er resultatet det samme?)
På samme måde kan man redde medianen af tre.
. gen median = y1 + y2 + y3 - min(y1, y2, y3) - max(y1, y2, y3)
Hvis y1, y2 og y3 alle mangler, har du allerede det eneste mulige svar: mangler. De situationer, der skal løses, er, at der kun mangler én variabel, og at der mangler to variabler i hver observation.
. replace median = max(y1, y2, y3) if (missing(y1) + missing(y2) + missing(y3)) == 2
Hvis der mangler to variabler, kan vi få den anden fra max(), og den er automatisk medianen.
. 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
Hvis der mangler én variabel, giver middelværdien af de to andre medianen. Vi sørger for, at der ikke tages hensyn til manglende oplysninger i summen ved at bruge 0 i stedet. Hvis vi vidste, at alle variabler skulle være positive (eller nul), kunne man bruge udtryk som max(y1, 0) i stedet for udtryk som cond(missing(y1), 0, y1), og hvis man vidste, at alle variabler skulle være negative (eller nul), kunne man bruge min(y1, 0) i stedet. Endvidere kunne man gøre det samme med egen:
. egen rowsum = rowsum(y1 y2 y3). replace median = rowsum / 2 ///if (missing(y1) + missing(y2) + missing(y3)) == 1
Selv om koden indtil nu har en vis kuriositetsværdi ved at vise, at man ikke altid behøver at sortere for at få rækkemedianer, har vi åbenbart virkelig brug for et program, der legemliggør en mere systematisk fremgangsmåde.
Der findes imidlertid ingen officiel egen-funktion til rækkemedianer. Hvis du søger efter community-contributed funktioner og ser nøje på dem, kan du begynde at se hvorfor. I det væsentlige var to tilgange mulige før Stata 9.
Den første, der er implementeret i egen, rmed() fra STB-57 (Stata 5 påkrævet), går ud på at løbe over observationer, kopiere værdier til en variabel og derefter få medianen. Desværre forudsætter denne fremgangsmåde, at antallet af berørte variabler ikke er større end antallet af observationer. Det er normalt, men ikke nødvendigvis sandt. Vigtigere er det, at denne fremgangsmåde faktisk kan være langsom.
Den anden, der er implementeret i egen, rmedf() fra SSC (Stata 6 påkrævet), er at omstrukturere datasættet i farten, beregne medianer og derefter omstrukturere tilbage. Man kan argumentere for, at omstrukturering af et datasæt ikke er noget, der bør gøres midt i en egen-funktion, men under alle omstændigheder kunne denne fremgangsmåde let mislykkes, hvis der ikke var nok hukommelse til rådighed.
Med Stata 9 kommer der imidlertid en mere positiv mulighed: at bruge Mata. Pakken egenmore på SSC indeholder egen, rowmedian(). Den er meget hurtigere end tidligere egen-funktioner – selv om den grundlæggende sløjfe stadig er en sløjfe over observationer – og den kræver kun lidt ekstra hukommelse. Her er koden:
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