我正在使用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
Run Code Online (Sandbox Code Playgroud)
而我正试图计算每家公司竞争对手的平均价格,所以我想创造一个新的领域,即市场中其他公司的平均价值.它看起来像:
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
Run Code Online (Sandbox Code Playgroud)
要按组进行平均,我可以使用egen命令:
egen AvPrice = mean(price), by(Market)
Run Code Online (Sandbox Code Playgroud)
但这并不排除公司自己的平均价格,据我所知,使用if限定符只会改变其运作的观察结果,而不会改变其平均的组.有一种简单的方法可以做到这一点,还是我需要创建循环并手动生成每个平均值?
这是一个仍然感兴趣的旧线程,因此第一轮忽略的材料和技术仍然适用.
更通用的技术是使用总计.最简单的是,总共有其他=总数 - 这个值.在一个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)
Run Code Online (Sandbox Code Playgroud)
在其参数total()中egen忽略缺失值的功能.如果存在缺失值,我们不希望将它们包含在计数中,但我们可以使用!missing()哪个产生1(如果没有丢失)和0(如果缺少).egen这count()是另一种方法.
如果存在缺失,则先前给出的代码会给出错误的答案,因为它们包含在计数中_N.
即使缺少一个值,其他值的平均值仍然有意义.
如果没有缺少值,则上面的最后一行简化为
gen avprice = (total - price) / (n - 1)
Run Code Online (Sandbox Code Playgroud)
到目前为止,这可能看起来只不过是以前代码的一个小变体,但它确实很容易扩展到使用权重.据推测,我们希望得到其他人的加权平均价格weight.我们可以利用total()对表达式起作用的事实,这可能比变量名更复杂.事实上,上面的代码已经做到了,但它经常被忽视.
egen wttotal = total(weight * price), by(market)
egen sumwt = total(weight), by(market)
gen avprice = (wttotal - price * weight) / (sumwt - weight)
Run Code Online (Sandbox Code Playgroud)
和以前一样,如果price或者weight曾经丢失过,您需要更复杂的代码,或者只是为了确保从计算中排除这些观察结果.
另请参阅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 |
+----------------------------------+
Run Code Online (Sandbox Code Playgroud)
这是一种避免显式循环的方法,尽管它需要几行代码:
by Market: egen Total = total(Price)
replace Total = Total - Price
by Market: gen AvRivalPrice = Total / (_N-1)
drop Total
Run Code Online (Sandbox Code Playgroud)
这是一个较短的解决方案,具有更少的线条,结合了您的原始思想和@ onestop的解决方案:
egen AvPrice = mean(price), by(Market)
bysort Market: replace AvPrice = (AvPrice*_N - price)/(_N-1)
Run Code Online (Sandbox Code Playgroud)
这对公司普查都有好处.如果你有公司的样本,并且你需要应用权重,我不确定什么是好的解决方案.如果需要,我们可以集思广益.