9

我正在使用 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

我正在尝试计算每个公司竞争对手的平均价格,所以我想生成一个新字段,它是市场中其他公司的平均值。它看起来像:

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

要按组进行平均,我可以使用 egen 命令:

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

但这并不排除公司自己的平均价格,据我所知,使用if限定词只会改变它所操作的观察结果,而不是它平均的组。有没有一种简单的方法可以做到这一点,还是我需要创建循环并手动生成每个平均值?

4

3 回答 3

9

这是一个仍然令人感兴趣的旧线程,因此第一次忽略的材料和技术仍然适用。

更通用的技术是使用总计。最简单的,其他人的总数=所有的总数-这个值。在一个egen看起来像的框架中

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) 

total()函数egen忽略其参数中的缺失值。如果有缺失值,我们不想将它们包含在计数中,但我们可以使用!missing()which 如果没有缺失则产生 1,如果缺失则产生 0。egen'scount()是另一种方法。

如果存在缺失,则前面给出的代码会给出错误的答案,因为它们包含在 count 中_N

即使缺少一个值,其他值的平均值仍然有意义。

如果没有缺少任何值,则上面的最后一行简化为

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

到目前为止,这可能看起来只是之前代码的一个小变体,但它确实很容易扩展到使用权重。假设我们想要给定一些其他价格的加权平均值weight。我们可以利用在表达式上起作用的事实total(),这可能比变量名更复杂。事实上,上面的代码已经做到了,但它经常被忽视。

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

和以前一样,如果priceweight曾经丢失,您需要更复杂的代码,或者只是为了确保您从计算中排除此类观察。

另请参阅 Stata 常见问题解答

如何为组中其他成员的每个单独属性创建变量汇总?

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

进行更广泛的讨论。

(如果数字变大,请使用doubles。)

编辑 2018 年 3 月 2 日那是旧线程中的较新帖子,而这又需要更新。rangestat(SSC)可以在这里使用并提供单线解决方案。毫不奇怪,excludeself为此类问题明确添加了该选项。但是,虽然手段的解决方案很容易使用身份

他人的平均值 =(总计 - 自我价值)/(计数 - 1)

许多其他的汇总措施不会产生类似的简单技巧,并且在这个意义上rangestat包括更通用的编码。

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 |
     +----------------------------------+
于 2013-02-20T10:52:21.197 回答
7

这是一种避免显式循环的方法,尽管它需要几行代码:

by Market: egen Total = total(Price)
replace Total = Total - Price
by Market: gen AvRivalPrice = Total / (_N-1)
drop Total
于 2012-03-06T11:29:47.493 回答
5

这是一个较短的解决方案,它结合了您的原始想法和@onestop 的解决方案:

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

这对于企业普查来说都是好事。如果您有公司样本,并且需要应用权重,我不确定什么是好的解决方案。如果需要,我们可以集思广益。

于 2012-03-07T02:46:20.707 回答