如果满足条件,则将变量的值提取到本地宏

时间:2016-11-26 23:21:03

标签: stata

我经常编写完成以下内容的for循环:

  1. 循环显示行标识符的值,如家庭号码
  2. 从其他变量中提取有关该家庭的信息
  3. 将该信息保存在本地宏
  4. 现在我这样做的方式似乎效率低下且不够优雅。以下示例说明了我的方法,该方法涉及创建新变量并在每次迭代中对数据进行排序。

    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' "'
    }
    

2 个答案:

答案 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的真正问题,但是我无法看到该技术所使用的任何暗示是良好的编程。