【问题标题】:Stata: foreach creates too many variables -Stata:foreach 创建了太多变量-
【发布时间】:2013-10-28 12:28:49
【问题描述】:

我在下面创建了我的代码的玩具示例。 在这个玩具示例中,我想创建一个自创建参考组中所有较高价格减去较低价格的度量。因此,在每个参考组中,我想将每个人从同一组中其他人的所有更高价格值中减去其价格值。我不想有负面的差异。然后我想总结所有这些差异。在创建此代码时,我在这里找到了一些帮助: 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*

【问题讨论】:

  • 尝试使用forvalues,因为它更简单、更高效(正如你提到的网站所说)
  • 谢谢,不幸的是我试过了,但遇到了同样的问题。

标签: for-loop stata


【解决方案1】:

如果我理解正确,这甚至不是需要显式循环的问题。所有更高价格的总和只是两个累积总和之间的差。如果价格捆绑,您可能需要考虑要做什么。

.清除 .设置 obs 10 obs 是 0,现在是 10 .基因组 = _n > 5 .设置种子 2803 .创价 = ceil(1000 * runiform()) .按排序组(价格):gen sumhigherprices = sum(price) .按组:替换 sumhigherprices = sumhigherprices[_N] - sumhigherprices (进行了 10 项实际更改) .列表 +----------------------------+ |团价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 

【讨论】:

  • 使用sum()也是回答你上一个问题stackoverflow.com/questions/17576316/…的关键!!!
  • 感谢您的帮助!抱歉,我没有看到解决方案之间的联系。我的意思略有不同:根据我的想法,您的组:1 sumhigherprices 应该看起来像 2527,2175,170,10,0。无论如何,我感谢您的帮助,再次抱歉,我没有看到问题之间的联系。
  • 感谢您的耐心和帮助。您的解决方案在玩具示例上完美运行。出于某种原因,我在数据集中得到了一些负值,还没有弄明白,但我会在这里留下评论以供将来参考。
  • 我确实警告过,捆绑价格需要考虑。
【解决方案2】:

如果我正确理解了问题的措辞,也许这会有所帮助。它使用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)

【讨论】:

  • joinby 是很好的Stata技术。需要注意的一件事是,一个大数据集可能至少暂时变得非常大。
  • 也谢谢你!不幸的是,我可以确认尼克所说的话。我刚才也试过你的解决方案,我得到:“扩展值的总和超过 2,147,483,647 数据集可能不包含超过 2,147,483,647 个观察值。”
  • 我应该明确指出这一点。尽管@NickCox 已经指出了这一点,但我已经编辑了该帖子以包含此内容。此外,如果您找到了解决问题的答案,您应该“接受”它并点击旁边的复选标记。
  • +1 在这里。尽管joinby 不适用于OP 的具体问题,但它是一个经常被忽视的命令。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-07-25
  • 1970-01-01
  • 2019-04-15
  • 2012-03-21
  • 2021-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多