În Stata 11, funcția rowmedian vă permite să calculați medianele rândurilor direct cu egen.
Cum se calculează medianele rândurilor?
Titlu | Calcularea medianelor rândurilor | |
Autor | Nicholas J. Cox, Durham University |
Calcularea medianelor într-un software statistic precum Stata ar trebui să fie ușoară, și de obicei este. Atunci când doriți o mediană pe rând – o mediană în cadrul observațiilor între mai multe variabile de același tip – pare mai complicat.
Această problemă merită o discuție, nu doar pentru că apare în practică. Ea oferă, de asemenea, un mic exemplu al diferitelor părți ale Stata în joc.
Pentru a recapitula elementele de bază: dacă doriți o mediană a unei variabile, ați putea să sortați pe acea variabilă și să alegeți singur mediana. Este necesară o anumită atenție ori de câte ori sunteți interesat doar de unele dintre observații sau există valori lipsă. De cele mai multe ori, utilizatorii pornesc summarize, detail, care se ocupă de toate aceste aspecte și identifică mediana în cadrul rezultatelor. Aceasta este apoi lăsată imediat în memorie ca r(p50).
Dacă, în schimb, doriți să puneți mediana într-o variabilă, puteți utiliza egen, median(). Acest lucru are cel mai mult sens atunci când datele dvs. sunt subdivizate în grupuri și doriți ca mediana fiecărui grup să fie înregistrată pentru utilizare ulterioară. Prin urmare, veți folosi egen, median() împreună cu by:.
Atunci când aveți o mulțime de variabile de același tip, uneori există un răspuns simplu. Dacă acele variabile sunt într-adevăr date de panel sau longitudinale, ar trebui să remodelați long și să lucrați cu o structură de date diferită. Viața va fi mult mai ușoară în acest fel, nu numai pentru mediile de rând, care sunt acum doar medii de panou, ci și pentru aproape toate tipurile de analiză pe care ați putea dori să le faceți cu astfel de date.
Dacă știți că valorile variabilelor de rând sunt în ordine numerică, astfel încât, de exemplu, y1 este întotdeauna mai mică sau egală cu y2, care, la rândul său, este mai mică sau egală cu y3, și așa mai departe, atunci mediana poate fi calculată direct fie ca una dintre variabile, fie ca media a două dintre variabile, în funcție de faptul că numărul de variabile este par sau impar. Dar acest lucru ar fi dat peste cap de orice valori lipsă.
Puteți ajunge la această situație a variabilelor de rând în ordine numerică folosind rowsort din SSC (necesită Stata 8; funcționează numai cu valori întregi) sau sortrows din SSC (necesită Stata 9).
Urmează situațiile în care aveți puține variabile (două, trei sau patru) peste care doriți să luați mediana de rând – și din nou nu lipsesc valori. Mediana a două variabile este aceeași cu media lor, așa că acest prim caz este ușor:
. gen median = (y1 + y2) / 2
Un truc mai puțin cunoscut pentru trei variabile face, de asemenea, ca rezolvarea problemei să fie simplă:
. gen median = y1 + y2 + y3 - min(y1, y2, y3) - max(y1, y2, y3)
Cu alte cuvinte: calculați suma rândurilor; apoi scădeți minimul și maximul. Ceea ce rămâne trebuie să fie mediana.
Acum, un truc pentru patru variabile este imediat:
. gen median = (y1 + y2 + y3 + y4 - /// min(y1, y2, y3, y4) - max(y1, y2, y3, y4)) / 2
Cu alte cuvinte: calculați suma rândurilor; apoi scădeți minimul și maximul. Ceea ce rămâne este suma celor două valori interioare, iar înjumătățirea dă mediana.
Trucuri simple pentru cinci sau mai multe variabile, în general, nu sunt în evidență.
Câteva reflecții arată că egalitățile nu pun probleme pentru nici unul dintre aceste trucuri. Ipoteza mai ciudată este că nu lipsesc valori. Există unele posibilități de salvare a problemelor cu valori lipsă. Puteți calcula numărul de variabile lipsă din
. egen nmissing = rowmiss(varlist)
, dar pentru câteva variabile, numărarea din mers a variabilelor lipsă este la fel de ușoară.
Cu orice variabile lipsă, mediana a două poate fi salvată prin
. gen median = (y1 + y2) / 2 . replace median = max(y1, y2) if median == .
Această secvență de comenzi exploatează faptul că max(y1, y2) este nonmissing ori de câte ori una dintre valori este. În cazul în care ambele valori lipsesc, nu pierdem cu adevărat, deoarece unele lipsuri sunt doar suprascrise de lipsuri. Ați putea scrie min(y1, y2) dacă acest lucru vă face să vă simțiți mai confortabil. (De ce este același rezultat?)
În mod similar, mediana a trei poate fi salvată.
. gen median = y1 + y2 + y3 - min(y1, y2, y3) - max(y1, y2, y3)
Dacă y1, y2 și y3 sunt toate lipsă, aveți deja singurul răspuns posibil: lipsă. Situațiile de rezolvat sunt că lipsește doar o singură variabilă și că lipsesc două variabile în fiecare observație.
. replace median = max(y1, y2, y3) if (missing(y1) + missing(y2) + missing(y3)) == 2
Dacă lipsesc două variabile, atunci o putem obține pe cealaltă din max() și aceasta este automat 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
Dacă lipsește o singură variabilă, atunci media celorlalte două dă mediana. Ne asigurăm că lipsurile sunt ignorate în sumă folosind în schimb 0. Dacă am ști că toate variabilele ar trebui să fie pozitive (sau zero), atunci ați putea folosi termeni precum max(y1, 0) în loc de termeni precum cond(missing(y1), 0, y1), iar dacă ați ști că toate variabilele ar trebui să fie negative (sau zero), ați putea folosi min(y1, 0) în loc de max(y1, 0). Mai mult, ați putea face același lucru cu egen:
. egen rowsum = rowsum(y1 y2 y3). replace median = rowsum / 2 ///if (missing(y1) + missing(y2) + missing(y3)) == 1
În mod evident, deși codul de până acum are o oarecare valoare de curiozitate prin faptul că arată că nu este întotdeauna nevoie să sortați pentru a obține medianele rândurilor, chiar avem nevoie de un program care să întruchipeze o abordare mai sistematică.
Cu toate acestea, nu există o funcție egen oficială pentru medianele rândurilor. Dacă căutați funcțiile contribuite de comunitate și le analizați cu atenție, puteți începe să înțelegeți de ce. În esență, două abordări erau posibile înainte de Stata 9.
Prima, implementată în egen, rmed() din STB-57 (Stata 5 necesar), este de a face o buclă peste observații, de a copia valorile într-o variabilă și apoi de a obține mediana. Din păcate, această abordare presupune că numărul de variabile în cauză nu este mai mare decât numărul de observații. Acest lucru este de obicei, dar nu neapărat adevărat. Mai important, această abordare poate fi într-adevăr lentă.
A doua, implementată în egen, rmedf() de la SSC (Stata 6 necesar), constă în restructurarea din mers a setului de date, calcularea medianei și apoi restructurarea din nou. Se poate argumenta că restructurarea unui set de date nu este ceva ce ar trebui făcut în mijlocul unei funcții egen, dar, în orice caz, această abordare ar putea eșua cu ușurință dacă nu ar fi disponibilă suficientă memorie.
Cu Stata 9, totuși, apare o oportunitate mai pozitivă: utilizarea lui Mata. Pachetul egenmore de pe SSC include egen, rowmedian(). Acesta este mult mai rapid decât funcțiile egen anterioare – chiar dacă bucla de bază este tot o buclă peste observații – și necesită puțină memorie suplimentară. Iată codul:
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
.