No Stata 11, a função rowmedian permite calcular medianas de linha diretamente com egen.
Como faço para calcular medianas de linha?
Título | Cálculo de medianas de linha | |
Autor | Nicholas J. Cox, Universidade de Durham |
Calcular medianas em software estatístico como o Stata deve ser fácil, e normalmente é. Quando você quer uma mediana de linha – uma mediana dentro das observações de várias variáveis da mesma família – parece mais complicado.
Este problema vale alguma discussão, não apenas porque ele surge na prática. Ele também fornece um pequeno exemplo de várias partes de Stata em jogo.
Para recapitular o básico: se você quiser uma mediana de uma variável, você mesmo poderia ordenar essa variável e escolher a mediana. Alguns cuidados são necessários sempre que estiver interessado apenas em algumas das observações ou se faltarem valores. Na maioria das vezes, os usuários fazem um resumo, um detalhe, que cuida de todos esses assuntos, e identificam a mediana dentro dos resultados. Ela é então deixada na memória imediatamente como r(p50).
Se você quiser colocar a mediana em uma variável, você pode usar egen, median(). Isto faz mais sentido quando os seus dados são subdivididos em grupos e você quer que cada mediana de grupo seja gravada para uso posterior. Assim você usaria egen, median() junto com por:.
Quando você tem um monte de variáveis do mesmo tipo, às vezes há uma resposta fácil. Se essas variáveis são realmente dados de painel ou longitudinais, você deve reformular a forma longa e trabalhar com uma estrutura de dados diferente. A vida será muito mais fácil assim, não apenas para as medianas de linha, que agora são apenas medianas de painel, mas também para quase todos os tipos de análise que você possa querer fazer com tais dados.
Se você sabe que os valores de suas variáveis de linha estão em ordem numérica, de modo que por exemplo y1 é sempre menor ou igual a y2, que por sua vez é menor ou igual a y3, e assim por diante, então a mediana pode ser calculada diretamente como uma das variáveis ou a média de duas das variáveis, dependendo se o número de variáveis é ímpar ou igual. Mas isso seria estragado por quaisquer valores em falta.
Você pode chegar a essa situação de variáveis de linha em ordem numérica usando a ordenação de linhas de SSC (requer Stata 8; funciona apenas com valores inteiros) ou ordenações de SSC (requer Stata 9).
Em seguida vêm as situações em que você tem poucas variáveis (duas, três ou quatro) sobre as quais você quer tomar a mediana da linha – e novamente nenhum valor está faltando. A mediana de duas variáveis é a mesma que a sua média, então o primeiro caso é fácil:
. gen median = (y1 + y2) / 2
Um truque menos conhecido para três variáveis também torna a solução do problema simples:
. gen median = y1 + y2 + y3 - min(y1, y2, y3) - max(y1, y2, y3)
Em palavras: trabalhe a soma das linhas; depois subtraia o mínimo e o máximo. O que resta deve ser a mediana.
Agora um truque para quatro variáveis é imediato:
. gen median = (y1 + y2 + y3 + y4 - /// min(y1, y2, y3, y4) - max(y1, y2, y3, y4)) / 2
Em palavras: calcula a soma das linhas; depois subtrai o mínimo e o máximo. O que resta é a soma dos dois valores internos, e reduzir pela metade dá a mediana.
Truques simples para cinco ou mais variáveis, em geral, não estão em evidência.
Alguns pensamentos mostram que os laços não representam nenhum problema para nenhum desses truques. A suposição mais constrangedora é que não faltam valores. Há alguma margem para salvar problemas com valores faltantes. Você pode calcular o número ausente a partir de
. egen nmissing = rowmiss(varlist)
mas para algumas variáveis, contar variáveis ausentes na hora é igualmente fácil.
Com qualquer variável ausente, a mediana de duas pode ser recuperada por
. gen median = (y1 + y2) / 2 . replace median = max(y1, y2) if median == .
Esta sequência de comandos explora o fato de que max(y1, y2) não é ausente sempre que um dos valores estiver. Se ambos os valores estiverem faltando, nós não perdemos realmente, já que alguns falhanços são apenas sobrescritos por falhanços. Você poderia escrever min(y1, y2) se isso o fizesse sentir mais confortável. (Por que o resultado é o mesmo?)
Da mesma forma, a mediana de três pode ser recuperada.
. gen median = y1 + y2 + y3 - min(y1, y2, y3) - max(y1, y2, y3)
Se y1, y2, e y3 estiverem todos em falta, você já tem a única resposta possível: em falta. As situações a corrigir são que apenas uma variável está faltando e que duas variáveis estão faltando em cada observação.
. replace median = max(y1, y2, y3) if (missing(y1) + missing(y2) + missing(y3)) == 2
Se duas variáveis estão faltando, então podemos obter a outra no max() e é automaticamente a 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
Se uma variável está faltando, então a média das outras duas dá a mediana. Nós asseguramos que as faltas são ignoradas na soma, usando 0 em vez disso. Se soubéssemos que todas as variáveis deveriam ser positivas (ou zero), então você poderia usar termos como max(y1, 0) em vez de termos como cond(missing(y1), 0, y1), e se você soubesse que todas as variáveis deveriam ser negativas (ou zero), você poderia usar min(y1, 0) em vez disso. Além disso, você poderia fazer a mesma coisa com egen:
. egen rowsum = rowsum(y1 y2 y3). replace median = rowsum / 2 ///if (missing(y1) + missing(y2) + missing(y3)) == 1
Manifestamente, embora o código até agora tenha algum valor de curiosidade em mostrar que você nem sempre precisa ordenar para obter medianas de linha, nós realmente precisamos de um programa que incorpore uma abordagem mais sistemática.
No entanto, não há nenhuma função oficial egen para medianas de linha. Se você procurar funções com contribuição da comunidade e olhar cuidadosamente para elas, você pode começar a ver o porquê. Em essência, duas abordagens eram possíveis antes do Stata 9.
A primeira, implementada no egen, rmed() do STB-57 (Stata 5 necessário), é fazer um loop sobre as observações, copiar os valores em uma variável e, em seguida, obter a mediana. Infelizmente, esta abordagem assume que o número de variáveis em questão não é maior do que o número de observações. Isto é normalmente, mas não necessariamente verdade. Mais importante, esta abordagem pode ser lenta de fato.
A segunda, implementada em egen, rmedf() da SSC (Stata 6 requerida), é reestruturar o conjunto de dados na mosca, calcular medianas, e então reestruturar de volta. É possível que a reestruturação de um conjunto de dados não seja algo que deva ser feito no meio de uma função egen, mas em qualquer caso esta abordagem poderia facilmente falhar se não houvesse memória suficiente.
Com Stata 9, no entanto, vem uma oportunidade mais positiva: usar Mata. O pacote egenmore no SSC inclui egen, rowmedian(). Ele é muito mais rápido que as funções anteriores do egen – embora o loop básico ainda seja um loop sobre as observações – e requer pouca memória extra. Aqui está o código:
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