Dans Stata 11, la fonction rowmedian vous permet de calculer les médianes de rangées directement avec egen.
Comment calculer les médianes de rangées ?
Titre | Calcul des médianes de rangées | |
Auteur | Nicholas J. Cox, Université de Durham |
Le calcul des médianes dans un logiciel statistique tel que Stata devrait être facile, et il l’est généralement. Lorsque vous voulez une médiane de ligne – une médiane au sein des observations sur plusieurs variables de même nature – cela semble plus délicat.
Ce problème mérite d’être discuté, et pas seulement parce qu’il se pose en pratique. Il fournit également un petit exemple de diverses parties de Stata en jeu.
Pour récapituler les bases : si vous voulez une médiane d’une variable, vous pourriez trier sur cette variable et choisir la médiane vous-même. Une certaine prudence est nécessaire chaque fois que vous êtes intéressé par seulement certaines des observations ou qu’il y a des valeurs manquantes. La plupart du temps, les utilisateurs lancent summarize, detail, qui s’occupe de toutes ces questions, et identifient la médiane dans les résultats. Elle est alors laissée en mémoire immédiatement comme r(p50).
Si vous voulez plutôt mettre la médiane dans une variable, vous pouvez utiliser egen, median(). Cela a plus de sens lorsque vos données sont subdivisées en groupes et que vous voulez que la médiane de chaque groupe soit enregistrée pour une utilisation ultérieure. D’où l’utilisation de egen, median() conjointement avec by :.
Lorsque vous avez un tas de variables du même type, il y a parfois une réponse facile. Si ces variables sont vraiment des données de panel ou longitudinales, vous devriez remodeler long et travailler avec une structure de données différente. La vie sera beaucoup plus facile de cette façon, non seulement pour les médianes de ligne, qui sont maintenant juste des médianes de panel, mais aussi pour presque tous les types d’analyse que vous pourriez vouloir faire avec de telles données.
Si vous savez que les valeurs de vos variables de ligne sont dans l’ordre numérique, de sorte que par exemple y1 est toujours inférieur ou égal à y2, qui à son tour est inférieur ou égal à y3, et ainsi de suite, alors la médiane peut être calculée directement comme l’une des variables ou la moyenne de deux des variables, selon que le nombre de variables est impair ou pair. Mais cela serait gâché par toutes les valeurs manquantes.
Vous pouvez arriver à cette situation de variables de ligne dans l’ordre numérique en utilisant rowsort de SSC (nécessite Stata 8 ; ne fonctionne qu’avec des valeurs entières) ou sortrows de SSC (nécessite Stata 9).
Viennent ensuite les situations où vous avez peu de variables (deux, trois ou quatre) sur lesquelles vous voulez prendre la médiane de ligne – et là encore, aucune valeur ne manque. La médiane de deux variables est la même que leur moyenne, donc ce premier cas est facile :
. gen median = (y1 + y2) / 2
Une astuce moins connue pour trois variables rend également la résolution du problème simple :
. gen median = y1 + y2 + y3 - min(y1, y2, y3) - max(y1, y2, y3)
En mots : calculez la somme des lignes ; puis soustrayez le minimum et le maximum. Ce qui reste doit être la médiane.
Maintenant, une astuce pour quatre variables est immédiate :
. gen median = (y1 + y2 + y3 + y4 - /// min(y1, y2, y3, y4) - max(y1, y2, y3, y4)) / 2
En mots : travaillez la somme des lignes ; puis soustrayez le minimum et le maximum. Ce qui reste est la somme des deux valeurs intérieures, et la division par deux donne la médiane.
Les astuces simples pour cinq variables ou plus, en général, ne sont pas en évidence.
Un peu de réflexion montre que les égalités ne posent aucun problème à aucune de ces astuces. L’hypothèse la plus gênante est qu’aucune valeur ne manque. Il existe une certaine marge de manœuvre pour sauver les problèmes de valeurs manquantes. Vous pouvez calculer le nombre manquant de
. egen nmissing = rowmiss(varlist)
mais pour quelques variables, compter les variables manquantes à la volée est tout aussi facile.
Avec n’importe quelles variables manquantes, la médiane de deux peut être récupérée par
. gen median = (y1 + y2) / 2 . replace median = max(y1, y2) if median == .
Cette séquence de commandes exploite le fait que max(y1, y2) est non manquant chaque fois qu’une des valeurs l’est. Si les deux valeurs sont manquantes, on ne perd pas vraiment au change, puisque certains manques sont juste écrasés par des manques. Vous pourriez écrire min(y1, y2) si cela vous mettait plus à l’aise. (Pourquoi le résultat est-il le même ?)
De même, la médiane de trois peut être sauvée.
. gen median = y1 + y2 + y3 - min(y1, y2, y3) - max(y1, y2, y3)
Si y1, y2 et y3 sont tous manquants, vous avez déjà la seule réponse possible : manquants. Les situations à corriger sont qu’une seule variable manque et que deux variables manquent dans chaque observation.
. replace median = max(y1, y2, y3) if (missing(y1) + missing(y2) + missing(y3)) == 2
Si deux variables manquent, alors on peut obtenir l’autre par max() et c’est automatiquement la médiane.
. 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
Si une variable manque, alors la moyenne des deux autres donne la médiane. Nous nous assurons que les manques sont ignorés dans la somme en utilisant 0 à la place. Si nous savions que toutes les variables devaient être positives (ou nulles), nous pourrions alors utiliser des termes tels que max(y1, 0) plutôt que des termes tels que cond(missing(y1), 0, y1), et si nous savions que toutes les variables devaient être négatives (ou nulles), nous pourrions utiliser min(y1, 0) à la place. De plus, vous pourriez faire la même chose avec egen:
. egen rowsum = rowsum(y1 y2 y3). replace median = rowsum / 2 ///if (missing(y1) + missing(y2) + missing(y3)) == 1
Manifestement, bien que le code jusqu’à présent ait une certaine valeur de curiosité en montrant que vous n’avez pas toujours besoin de trier pour obtenir des médianes de lignes, nous avons vraiment besoin d’un programme incarnant une approche plus systématique.
Cependant, il n’y a pas de fonction egen officielle pour les médianes de lignes. Si vous recherchez les fonctions contribuées par la communauté et que vous les examinez attentivement, vous pouvez commencer à voir pourquoi. Essentiellement, deux approches étaient possibles avant Stata 9.
La première, implémentée dans egen, rmed() de STB-57 (Stata 5 requis), consiste à boucler sur les observations, copier les valeurs dans une variable et ensuite obtenir la médiane. Malheureusement, cette approche suppose que le nombre de variables concernées n’est pas supérieur au nombre d’observations. C’est généralement mais pas nécessairement vrai. Plus important encore, cette approche peut être effectivement lente.
La seconde, implémentée dans egen, rmedf() de SSC (Stata 6 requis), consiste à restructurer l’ensemble de données à la volée, à calculer les médianes, puis à restructurer à nouveau. On peut soutenir que la restructuration d’un ensemble de données n’est pas quelque chose qui devrait être fait au milieu d’une fonction egen, mais dans tous les cas, cette approche pourrait facilement échouer si suffisamment de mémoire n’était pas disponible.
Avec Stata 9, cependant, vient une opportunité plus positive : utiliser Mata. Le paquet egenmore sur SSC comprend egen, rowmedian(). Elle est beaucoup plus rapide que les fonctions egen précédentes – même si la boucle de base est toujours une boucle sur les observations – et elle nécessite peu de mémoire supplémentaire. Voici le 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