在索引中使用宏循环时出错
error when looping with macros in the indexing
I am trying to create a dummy variable to identify the next five observations after a selection of cutoffs. The first method in the code below works, but it looks a bit messy and I'd like to be able to adjust the number of observations I'm creating dummies for without typing out the same expression 30 times (usually a sign I'm doing something the hard way).
Every time I put a macro into the indexing, i.e.
[_n-`i']
我收到以下错误:
_= invalid name
r(198);
I'd be very grateful for some advice.
sysuse auto.dta, replace
global cutoffs 3299 4424 5104 5788 10371
This works
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'
}
This doesn't.
foreach x in $cutoffs {
forval `i' = 0/25 {
replace A=1 if price[_n-`i']==`x'
}
}
Any advice as to why?
在 Stata 术语中,这里根本不需要循环,除了 generate
和 replace
中默认的循环。您希望在每次达到截止点后立即设置一个计数器,然后确定 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 |
+---------------------------+
事实上,您的文字说 "the next five observations after" 但您的代码不仅实现了这一点,还实现了截止观察。对于后者,使用 inrange(counter, 0, 5)
。
理解所解释的原则here对于这个问题至关重要。
对于 inrange()
和 inlist()
,请参阅他们的帮助条目 and/or this paper。
那么,你做错了什么?
这一行
forval `i' = 0/25 {
是非法的,除非您之前已经定义了本地宏 i
(即使那样也是相当奇怪的风格)。你的意思可能是
forval i = 0/25 {
虽然根据你的问题陈述,25 是从哪里来的,但我不清楚。错误消息不是特别有用,但 Stata 正在努力理解其中有漏洞的代码,因为您的代码隐含的本地宏未定义。
I am trying to create a dummy variable to identify the next five observations after a selection of cutoffs. The first method in the code below works, but it looks a bit messy and I'd like to be able to adjust the number of observations I'm creating dummies for without typing out the same expression 30 times (usually a sign I'm doing something the hard way).
Every time I put a macro into the indexing, i.e.
[_n-`i']
我收到以下错误:
_= invalid name
r(198);
I'd be very grateful for some advice.
sysuse auto.dta, replace
global cutoffs 3299 4424 5104 5788 10371
This works
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'
}
This doesn't.
foreach x in $cutoffs {
forval `i' = 0/25 {
replace A=1 if price[_n-`i']==`x'
}
}
Any advice as to why?
在 Stata 术语中,这里根本不需要循环,除了 generate
和 replace
中默认的循环。您希望在每次达到截止点后立即设置一个计数器,然后确定 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 |
+---------------------------+
事实上,您的文字说 "the next five observations after" 但您的代码不仅实现了这一点,还实现了截止观察。对于后者,使用 inrange(counter, 0, 5)
。
理解所解释的原则here对于这个问题至关重要。
对于 inrange()
和 inlist()
,请参阅他们的帮助条目 and/or this paper。
那么,你做错了什么?
这一行
forval `i' = 0/25 {
是非法的,除非您之前已经定义了本地宏 i
(即使那样也是相当奇怪的风格)。你的意思可能是
forval i = 0/25 {
虽然根据你的问题陈述,25 是从哪里来的,但我不清楚。错误消息不是特别有用,但 Stata 正在努力理解其中有漏洞的代码,因为您的代码隐含的本地宏未定义。