【问题标题】:Stata Nested foreach loop substring comparisonStata嵌套foreach循环子字符串比较
【发布时间】:2014-12-06 22:55:30
【问题描述】:

我刚刚开始学习 Stata,我遇到了困难。 我的问题是:我有两个不同的变量ATCA,其中A 可能是ATC 的子字符串。 现在我想用OK = 1 标记AATC 的子串的所有观察结果。

我用一个简单的嵌套循环尝试了这个:

foreach x in ATC {
foreach j in A {
        replace OK = 1 if strpos(`x',`j')!=0
    }
}

但是,无论何时我运行此循环,都不会进行任何更改,即使应该有很多。 我觉得我可能应该给出一个索引,指定正在更改哪个OK(属于ATC/x 的那个),但我不知道该怎么做。这可能真的很简单,但我已经为此苦苦挣扎了一段时间。


我应该澄清一下:我的 A 列表与主列表是分开的(只是附加到它上面),并且只包含我用来识别我想要的 ATCs 的唯一键。所以我有 ~120 个 A-keys 和几百万个 ATC 键。我想做的是为每个A-key 遍历每个ATC 键,并用A 标记那些符合条件的ATC-keys。

这意味着我没有完整的 (ATC,A,OK) 元组,而是不同大小的单独列表。 例如:我有

ATC    OK  A 
ABCD   0   .
EFGH   0   .
...   ...  ...
.     .    AB
.     .    ET

并希望将具有OK"ABCD" 标记为1"EFGH" 保持在0 的结果。

【问题讨论】:

    标签: loops foreach nested substring stata


    【解决方案1】:

    我们可以将您的问题分为两部分。您的标题暗示循环存在问题,但您的循环仅相当于

      replace OK = 1 if strpos(ATC, A)!=0
    

    所以循环的使用似乎无关紧要。这留下了子字符串比较。

    举个例子:

    . set obs 3 
    obs was 0, now 3
    
    . gen OK = 0 
    
    . gen A = cond(_n == 1, "42", "something else")  
    
    . gen ATC = "answer is 42"
    
    . replace OK = 1 if strpos(ATC, A) != 0 
    (1 real change made)
    
    . list 
    
         +------------------------------------+
        | OK                A            ATC |
        |------------------------------------|
     1. |  1               42   answer is 42 |
     2. |  0   something else   answer is 42 |
     3. |  0   something else   answer is 42 |
        +------------------------------------+
    

    所以它工作正常;如果你认为你有不同的东西,你真的需要给出一个可重复的例子。

    至于指定应该更改变量的位置:您的代码正是这样做的,正如上面的示例所示。


    更新使问题变得清晰。当您指定您给出的语法时,Stata 只会在相同的观察中查找匹配的子字符串。 Stata 中的变量是数据集中的一个字段。要循环一组值,这样的事情就足够了

     gen byte OK = 0 
     levelsof A, local(Avals) 
    
     quietly foreach A of local Avals { 
         replace OK = 1 if strpos(ATC, `"`A'"') > 0 
     } 
    

    注意事项:

    1. 指定 byte 会减少存储空间。

    2. 您可能需要对levelsof 进行ifin 限制。

    3. quietly 删除有关更改值的消息。调试时,通常最好忽略它。

    4. > 0 可以省略,因为strpos() 的肯定结果在逻辑比较中自动被视为真。见this FAQ

    【讨论】:

    • 我编辑了我的原始帖子。我可能应该从一开始就举一个例子,谢谢你的帮助。我为我糟糕的格式等道歉,因为我不经常使用这个网站。
    猜你喜欢
    • 2023-03-25
    • 2016-01-23
    • 2013-04-05
    • 1970-01-01
    • 2021-07-14
    • 2017-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多