2012-03-06 31 views
9

Estoy usando Stata, y estoy tratando de calcular el precio promedio de los rivales de las empresas en un mercado. Tengo los datos que se parece a:Usando if calificador con egen en Stata

Market Firm Price 
---------------------- 
1   1  100 
1   2  150 
1   3  125 
2   1  50 
2   2  100 
2   3  75 
3   1  100 
3   2  200 
3   3  200 

Y estoy tratando de calcular el precio medio de los rivales de cada empresa, por lo que quiero para generar un nuevo campo que es los valores medios de las otras empresas en un mercado. Que se vería así:

Market Firm Price AvRivalPrice 
------------------------------------ 
1   1  100  137.2 
1   2  150  112.5 
1   3  125  125 
2   1  50  87.5 
2   2  100  62.5 
2   3  75  75 
3   1  100  200 
3   2  200  150 
3   3  200  150 

Para hacer la media por grupo, que podría utilizar el comando egen:

egen AvPrice = mean(price), by(Market) 

Pero eso no excluye propio precio de la firma en la media, y para la lo mejor de mi conocimiento, usar el calificador if solo cambiaría las observaciones que operaba, no los grupos sobre los que promedió. ¿Hay una manera simple de hacer esto o necesito crear bucles y generar cada promedio manualmente?

+0

U puede dar un pequeño ejemplo de cálculo ur ... Es wud hacer mucho más clara – Teja

+0

lo hice (la tabla de datos es el ejemplo de lo que). – prototoast

+0

El 'if' del que se habla no es el comando' if', sino el calificador 'if'. He editado en consecuencia. –

Respuesta

7

Esta es una manera que evita bucles explícitas, aunque se tarda varias líneas de código:

by Market: egen Total = total(Price) 
replace Total = Total - Price 
by Market: gen AvRivalPrice = Total/(_N-1) 
drop Total 
+0

Esto producirá un mensaje de error si los datos no están ordenados por 'Market'. Tiene que ser 'bysort', al menos en el primer caso. – StasK

5

Aquí hay una solución más corto con menos líneas de ese tipo de combina el pensamiento original y la solución de @ onestop:

 egen AvPrice = mean(price), by(Market) 
     bysort Market: replace AvPrice = (AvPrice*_N - price)/(_N-1) 

Todo esto es bueno para un censo de empresas. Si tiene una muestra de las empresas y necesita aplicar los pesos, no estoy seguro de cuál sería una buena solución. Podemos hacer una lluvia de ideas si es necesario.

+0

Gracias, pude manejar las modificaciones para convertirlo en una muestra (tomó algunas líneas adicionales), pero esto me hizo pensar en la dirección correcta. – prototoast

8

Este es un hilo antiguo que sigue siendo de interés, por lo que todavía se aplican materiales y técnicas que se pasaron por alto la primera vuelta.

La técnica más general es trabajar con totales. En su forma más simple, total de otros = total de todos - este valor. En un marco egen que va a parecerse a

egen total = total(price), by(market) 
egen n = total(!missing(price)), by(market) 
gen avprice = (total - cond(missing(price), 0, price))/cond(missing(price), n, n - 1) 

La función de total()egen ignora los valores que faltan en su argumento. Si faltan valores, no queremos incluirlos en el recuento, pero podemos usar !missing(), que arroja 1 si no falta y 0 si falta. egen 's count() es otra manera de hacer esto.

El código proporcionado anteriormente da la respuesta incorrecta si hay errores presentes, ya que están incluidos en el recuento _N.

Incluso si falta un valor, el promedio de los otros valores sigue teniendo sentido.

Si no hay valor no está presente, la última línea anterior se simplifica a

gen avprice = (total - price)/(n - 1) 

Hasta ahora, esto posiblemente se parece más que una pequeña variante en el código anterior, pero se extiende fácilmente a usar pesos. Es de suponer que queremos un promedio ponderado de los precios de los demás dados algunos weight. Podemos explotar el hecho de que total() funciona en expresiones, que pueden ser más complicadas que los nombres de variables. De hecho, el código anterior ya lo hizo, pero a menudo se pasa por alto.

egen wttotal = total(weight * price), by(market) 
egen sumwt = total(weight), by(market) 
gen avprice = (wttotal - price * weight)/(sumwt - weight) 

Como antes, si price o weight está siempre faltan, es necesario un código más complicado, o simplemente para asegurarse de que se excluye este tipo de observaciones de los cálculos.

Véase también el FAQ Stata

¿Cómo creo que resumen las variables para cada propiedades individuales de los otros miembros de un grupo?

http://www.stata.com/support/faqs/data-management/creating-variables-recording-properties/

para una discusión de mayor alcance.

(Si los números se hacen grandes, trabajar con double s.)

EDIT 2 de marzo de 2018 fue un nuevo mensaje en un hilo de edad, que a su vez necesita una reforma. rangestat (SSC) se puede utilizar aquí y ofrece soluciones de una línea. No en vano, la opción excludeself se agregó explícitamente para este tipo de problemas. Pero mientras que la solución de los medios es muy fácil usando una identidad

significa para los demás = (Total - valor para la auto)/(Count - 1)

muchas otras medidas de resumen no ceden a un truco similar, sencillo y en ese sentido rangestat incluye una codificación mucho más general.

clear 
input Market Firm Price 
1   1  100 
1   2  150 
1   3  125 
2   1  50 
2   2  100 
2   3  75 
3   1  100 
3   2  200 
3   3  200 
end 

rangestat (mean) Price, interval(Firm . .) by(Market) excludeself 

list, sepby(Market) 

    +----------------------------------+ 
    | Market Firm Price Price_~n | 
    |----------------------------------| 
    1. |  1  1  100  137.5 | 
    2. |  1  2  150  112.5 | 
    3. |  1  3  125  125 | 
    |----------------------------------| 
    4. |  2  1  50  87.5 | 
    5. |  2  2  100  62.5 | 
    6. |  2  3  75   75 | 
    |----------------------------------| 
    7. |  3  1  100  200 | 
    8. |  3  2  200  150 | 
    9. |  3  3  200  150 | 
    +----------------------------------+ 
Cuestiones relacionadas