2016-11-26 136 views
-1

我经常写for循环即完成下列工作:通过一个行标识符像家庭号码有关家庭从 提取值,如果条件满足

  • 提取信息的值

    1. 周期其他变量
    2. 现在保存在本地宏

    信息我这样做似乎效率不高和不雅的方式。以下示例说明了我的方法,其中涉及创建一个新变量并对每次迭代中的数据进行排序。

    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

    我很少遇到我必须通过观察循环的情况。我可以使用'by variable:egen'完成大部分繁琐的工作。例如,您可以为另一个变量的每个值获取变量的平均值,总和,计数等。您也可以使用'mkmat'和'svmat'从变量创建矩阵,反之亦然,然后使用矩阵运算符。 – chan1142

    +0

    我不明白你为什么认为你需要一个循环,即使你编辑的问题。给定一个二进制变量'treat'以某种方式创建,你的代码基本上等同于'list weight make if treat == 1'加上一些重复的文本。如果计数器很重要,你可以'生成',单独添加到'list',但即使如此,本地宏和循环在这里完全是可有可无的。我猜你对于需要循环的语言更熟悉,但在Stata中,它们通常不需要用于基本任务。 –

    +0

    @Nick,我的实际使用比简单列出一些值更复杂一点,但我想保持简单。这就是为什么在我最初的例子中,我所说的只是“用宏做些事情”。为了不从我的问题的核心中分心,我大大简化了示例,以便我可以使用已发布的自动数据集,不需要读者安装用户编写的命令,也不需要解释30行以上代码的逻辑循环,当那些东西实际上不是我的问题需要.. – Amberopolis

    回答

    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']' "' 
        } 
    
    +0

    要增加William的有用答案,让我强调一点,你根本不需要变量'temp'。事实上,你根本不需要任何循环。 '列表重量make'在这里基本上是等价的。 –

    +0

    @William,你是对的,我打算循环观察的一个子集。但考虑到这一点,我无法想出一个解决方案(遍历所有obs)或我的编辑解决方案(通过子集)无法工作的场景。感谢您帮助澄清我的想法! – Amberopolis

    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 -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的代理真正的问题,但我看不到任何暗示这种技术是好的编程。