在索引中使用宏循环时出错

时间:2016-08-08 14:04:40

标签: indexing stata stata-macros

我正在尝试创建一个虚拟变量,以便在选择截止值后识别接下来的五个观察值。下面的代码中的第一个方法有效,但它看起来有点乱,我希望能够调整我正在创建虚拟对象的观察次数,而无需输入相同的表达式30次(通常是一个符号我是做一些艰难的事情)。

每次我将宏放入索引中,即

[_n-`i'] 

我收到以下错误:

 _= invalid name
r(198);

我非常感谢你提出一些建议。

sysuse auto.dta, replace
global cutoffs 3299 4424 5104 5788 10371

这有效

sort price
gen A=0

foreach x in $cutoffs {
    replace A=1 if price==`x' 
    replace A=1 if price[_n-1]==`x'
    replace A=1 if price[_n-2]==`x'
    replace A=1 if price[_n-3]==`x'
    replace A=1 if price[_n-4]==`x'
    replace A=1 if price[_n-5]==`x'
}

这不是。

foreach x in $cutoffs {
    forval `i' = 0/25 { 
        replace A=1 if price[_n-`i']==`x'
    }
}

有关原因的任何建议吗?

1 个答案:

答案 0 :(得分:1)

在Stata术语中,除了generatereplace中的隐含之外,根本不需要任何循环。您希望在达到截止值后立即设置计数器,然后识别1到5之间的计数器值。这是一些技巧:

sysuse auto.dta, clear 
global cutoffs 3299,4424,5104,5788,10371
sort price 

gen counter = 0 if inlist(price, $cutoffs) 
replace counter = counter[_n-1] + 1 if missing(counter) 
gen wanted = inrange(counter, 1, 5) 

list price counter wanted 

     +---------------------------+
     |  price   counter   wanted |
     |---------------------------|
  1. |  3,291         .        0 |
  2. |  3,299         0        0 |
  3. |  3,667         1        1 |
  4. |  3,748         2        1 |
  5. |  3,798         3        1 |
     |---------------------------|
  6. |  3,799         4        1 |
  7. |  3,829         5        1 |
  8. |  3,895         6        0 |
  9. |  3,955         7        0 |
 10. |  3,984         8        0 |
     |---------------------------|
 11. |  3,995         9        0 |
 12. |  4,010        10        0 |
 13. |  4,060        11        0 |
 14. |  4,082        12        0 |
 15. |  4,099        13        0 |
     |---------------------------|
 16. |  4,172        14        0 |
 17. |  4,181        15        0 |
 18. |  4,187        16        0 |
 19. |  4,195        17        0 |
 20. |  4,296        18        0 |
     |---------------------------|
 21. |  4,389        19        0 |
 22. |  4,424         0        0 |
 23. |  4,425         1        1 |
 24. |  4,453         2        1 |
 25. |  4,482         3        1 |
     |---------------------------|
 26. |  4,499         4        1 |
 27. |  4,504         5        1 |
 28. |  4,516         6        0 |
 29. |  4,589         7        0 |
 30. |  4,647         8        0 |
     |---------------------------|
 31. |  4,697         9        0 |
 32. |  4,723        10        0 |
 33. |  4,733        11        0 |
 34. |  4,749        12        0 |
 35. |  4,816        13        0 |
     |---------------------------|
 36. |  4,890        14        0 |
 37. |  4,934        15        0 |
 38. |  5,079        16        0 |
 39. |  5,104         0        0 |
 40. |  5,172         1        1 |
     |---------------------------|
 41. |  5,189         2        1 |
 42. |  5,222         3        1 |
 43. |  5,379         4        1 |
 44. |  5,397         5        1 |
 45. |  5,705         6        0 |
     |---------------------------|
 46. |  5,719         7        0 |
 47. |  5,788         0        0 |
 48. |  5,798         1        1 |
 49. |  5,799         2        1 |
 50. |  5,886         3        1 |
     |---------------------------|
 51. |  5,899         4        1 |
 52. |  6,165         5        1 |
 53. |  6,229         6        0 |
 54. |  6,295         7        0 |
 55. |  6,303         8        0 |
     |---------------------------|
 56. |  6,342         9        0 |
 57. |  6,486        10        0 |
 58. |  6,850        11        0 |
 59. |  7,140        12        0 |
 60. |  7,827        13        0 |
     |---------------------------|
 61. |  8,129        14        0 |
 62. |  8,814        15        0 |
 63. |  9,690        16        0 |
 64. |  9,735        17        0 |
 65. | 10,371         0        0 |
     |---------------------------|
 66. | 10,372         1        1 |
 67. | 11,385         2        1 |
 68. | 11,497         3        1 |
 69. | 11,995         4        1 |
 70. | 12,990         5        1 |
     |---------------------------|
 71. | 13,466         6        0 |
 72. | 13,594         7        0 |
 73. | 14,500         8        0 |
 74. | 15,906         9        0 |
     +---------------------------+

事实上,你的文字说“接下来的五个观察结果”,但你的代码不只是那个,而是截止观察。对于后者,请使用inrange(counter, 0, 5)

理解解释的原则here对于这个问题至关重要。

对于inrange()inlist(),请参阅他们的帮助条目和/或this paper

那么,你做错了什么?

这一行

 forval `i' = 0/25 { 

非法,除非您之前已经定义了本地宏i(甚至是奇怪的样式)。你或许意味着

 forval i = 0/25 { 

虽然25来自哪里,但鉴于你的问题陈述,我不清楚。错误消息不是特别有用,但是Stata正在努力理解带有漏洞的代码,因为代码隐含的本地宏没有定义。