我经常编写完成以下内容的for循环:
现在我这样做的方式似乎效率低下且不够优雅。以下示例说明了我的方法,该方法涉及创建新变量并在每次迭代中对数据进行排序。
sysuse auto
gen obs_id = _n
foreach i of numlist 1/74{
*Create variable to get observation to row 1
gen temp = 1 if obs_id == `i'
sort temp
*Extract information
local w = weight[1]
local ma = make[1]
*Do something with the macros
drop temp
}
有时我会对所有数字变量执行此操作,因此我使用
sum weight if obs_id == `i'
local w = r(mean)
反而在循环内部,效率更高。
但是有没有办法以比这更合理的方式保存变量中的信息?
编辑添加: 正如威廉的回答所暗示的那样,我的意图是来对观察的一个子集进行分类,其中子集由一些虚拟变量识别(即,对待= 1)。但即便如此,也可以通过威廉的基本逻辑来处理,如下:
sysuse auto
set seed 1234
gen random = uniform()
gen treat = 0
replace treat = 1 if random > 0.7
sum treat if treat == 1
local n = r(N)
bysort treat: gen counter = _n if treat == 1
sort counter
foreach i of numlist 1/`n'{
local w = weight[`i']
local ma = make[`i']
display `"treated unit `i' - `w' `ma' "'
}
答案 0 :(得分:2)
您的示例处理数据集中的每一行。假设你想要对你的真实数据做些什么(但我怀疑你真的想要处理一小部分obs_id值的观察结果),下面的内容会更直接地完成。
sysuse auto, clear
forvalues i = 1/`= _N' {
local w = weight[`i']
local ma = make[`i']
display `"observation `i' - `w' `ma' "'
}
这可以进一步简化为
sysuse auto, clear
forvalues i = 1/`= _N' {
display `"observation `i' - `= weight[`i']' `=make[`i']' "'
}
答案 1 :(得分:0)
这个答案强调了我的观点,即OP的循环是完全可以避免的。
(如果想要一次又一次地看到文字treated unit
,那么generate text = "treated unit"
并将其包含在list
中。
sysuse auto, clear
set seed 1234
gen random = uniform()
gen treat = 0
replace treat = 1 if random > 0.7
sum treat if treat == 1
local n = r(N)
bysort treat: gen counter = _n if treat == 1
sort counter
* OP's method
foreach i of numlist 1/`n'{
local w = weight[`i']
local ma = make[`i']
display `"treated unit `i' - `w' `ma' "'
}
treated unit 1 - 3670 Buick LeSabre
treated unit 2 - 4330 Cad. Deville
treated unit 3 - 3400 Buick Skylark
treated unit 4 - 3180 Chev. Malibu
treated unit 5 - 2930 AMC Concord
treated unit 6 - 2690 Pont. Sunbird
treated unit 7 - 3210 Pont. Grand Prix
treated unit 8 - 2200 Plym. Horizon
treated unit 9 - 2070 Audi Fox
treated unit 10 - 2640 AMC Spirit
treated unit 11 - 3720 Merc. Marquis
treated unit 12 - 2110 Chev. Chevette
treated unit 13 - 3690 Olds Delta 88
treated unit 14 - 3600 Dodge Magnum
treated unit 15 - 4060 Merc. Cougar
treated unit 16 - 3420 Pont. Phoenix
treated unit 17 - 3260 Plym. Arrow
treated unit 18 - 2130 Fiat Strada
treated unit 19 - 3200 Pont. Le Mans
treated unit 20 - 2410 Toyota Celica
treated unit 21 - 2670 Toyota Corona
treated unit 22 - 2230 Buick Opel
treated unit 23 - 3250 Buick Century
treated unit 24 - 1800 Plym. Champ
treated unit 25 - 2730 Olds Starfire
treated unit 26 - 3280 Buick Regal
treated unit 27 - 1800 Ford Fiesta
treated unit 28 - 1830 Renault Le Car
* alternative
list weight make if treat
+---------------------------+
| weight make |
|---------------------------|
1. | 3,670 Buick LeSabre |
2. | 4,330 Cad. Deville |
3. | 3,400 Buick Skylark |
4. | 3,180 Chev. Malibu |
5. | 2,930 AMC Concord |
|---------------------------|
6. | 2,690 Pont. Sunbird |
7. | 3,210 Pont. Grand Prix |
8. | 2,200 Plym. Horizon |
9. | 2,070 Audi Fox |
10. | 2,640 AMC Spirit |
|---------------------------|
11. | 3,720 Merc. Marquis |
12. | 2,110 Chev. Chevette |
13. | 3,690 Olds Delta 88 |
14. | 3,600 Dodge Magnum |
15. | 4,060 Merc. Cougar |
|---------------------------|
16. | 3,420 Pont. Phoenix |
17. | 3,260 Plym. Arrow |
18. | 2,130 Fiat Strada |
19. | 3,200 Pont. Le Mans |
20. | 2,410 Toyota Celica |
|---------------------------|
21. | 2,670 Toyota Corona |
22. | 2,230 Buick Opel |
23. | 3,250 Buick Century |
24. | 1,800 Plym. Champ |
25. | 2,730 Olds Starfire |
|---------------------------|
26. | 3,280 Buick Regal |
27. | 1,800 Ford Fiesta |
28. | 1,830 Renault Le Car |
+---------------------------+
当然,我很高兴地相信这个玩具问题代表了OP的真正问题,但是我无法看到该技术所使用的任何暗示是良好的编程。