我在下面创建了我的代码的玩具示例。 在这个玩具示例中,我想在自创参考组中创建一个所有较高价格减去较低价格的度量。因此,在每个参考组中,我想取每个人并从同一组中其他个人的所有较高价格值中减去其价格值。我不想有负面的差异。然后我想总结所有这些差异。在创建此代码时,我在此处找到了一些帮助: http://www.stata.com/support/faqs/data-management/try-all-values-with-foreach/
然而,代码对我来说不是很完美,因为我的数据集非常大(几个100K obs),网站上的示例和我的代码只能在Stata中的numlist最大值1600之前工作。 (我使用的是版本12)。由于数据集的小尺寸,具有自动数据集的玩具示例正常工作。
我想问一下是否有人知道如何更有效地编码,以便我可以绕过numlist限制。我想直接总结差异而不将它们保存在中间变量中,但这也会炸掉numlist限制。
clear all
sysuse auto
ren headroom refgroup
bysort refgroup : egen pricerank = rank(price)
qui: su pricerank, meanonly
gen test = `r(max)'
su test
foreach i of num 1/`r(max)' {
qui: bys refgroup: gen intermediate`i' = price[_n+`i'] -price if price[_n+`i'] > price
}
egen price_diff = rowmax(intermediate*)
drop intermediate*
答案 0 :(得分:1)
如果我理解正确,这甚至不是需要显式循环的问题。所有较高价格的总和只是两个累积金额之间的差异。如果价格挂钩,您可能需要考虑您想要做的事情。
. clear . set obs 10 obs was 0, now 10 . gen group = _n > 5 . set seed 2803 . gen price = ceil(1000 * runiform()) . bysort group (price) : gen sumhigherprices = sum(price) . by group : replace sumhigherprices = sumhigherprices[_N] - sumhigherprices (10 real changes made) . list +--------------------------+ | group price sumhig~s | |--------------------------| 1. | 0 218 1448 | 2. | 0 264 1184 | 3. | 0 301 883 | 4. | 0 335 548 | 5. | 0 548 0 | |--------------------------| 6. | 1 125 3027 | 7. | 1 213 2814 | 8. | 1 828 1986 | 9. | 1 988 998 | 10. | 1 998 0 | +--------------------------+
编辑:对于OP需要什么,还有一个额外的行
. by group : replace sumhigherprices = sumhigherprices - (_N - _n) * price
答案 1 :(得分:1)
如果我正确理解问题的措辞,也许这会有所帮助。它使用joinby
(创建新的观察结果,根据原始数据库的大小,您可能会或不会达到Stata对观察数量的硬限制)。该代码再现了原始帖子代码后面的结果。这是第二次尝试。最终编辑之前的代码没有提供广受欢迎的结果。问题的措辞对我来说有点难以理解。
clear all
set more off
* Load data
sysuse auto
* Delete unnecessary vars
ren headroom refgroup
keep refgroup price
* Generate id´s based on rankings (sort)
bysort refgroup (price): gen id = _n
* Pretty list
order refgroup id
sort refgroup id price
list, sepby(refgroup)
* joinby procedure
tempfile main
save "`main'"
rename (price id) =0
joinby refgroup using "`main'"
list, sepby(refgroup)
* Do not compare with itself and drop duplicates
drop if id0 >= id
* Compute differences and max
gen dif = abs(price0 - price)
collapse (max) dif, by(refgroup id0)
list, sepby(refgroup)