Stata嵌套的foreach循环子串比较

use*_*050 0 foreach loops nested substring stata

我刚刚开始学习Stata,我很难过.我的问题是:我有两个不同的变量,ATC并且A,其中A可能是子串ATC.现在我想,以纪念所有的意见中,A是的一个子ATCOK = 1.

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

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

但是,每当我运行此循环时,即使应该有足够的数据,也不会进行任何更改.我觉得我应该给出一个索引来指定哪个OK被更改(属于ATC/ x的那个),但我不知道如何做到这一点.这可能非常简单,但我已经挣扎了一段时间.


我应该澄清一下:我的A列表与主列表分开(只是附加到它),并且只包含我用来识别ATC我想要的s的唯一键.所以我有~120个A键和几百万个ATC键.我想要做的是迭代每个ATC单键的每个A键,并标记那些ATC具有A该限定条件的键.

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

ATC    OK  A 
ABCD   0   .
EFGH   0   .
...   ...  ...
.     .    AB
.     .    ET
Run Code Online (Sandbox Code Playgroud)

并希望结果"ABCD"已经OK被标记为1同时"EFGH"保持在0.

Nic*_*Cox 5

我们可以将您的问题分成两部分.你的标题意味着循环问题,但你的循环只相当于

  replace OK = 1 if strpos(ATC, A)!=0
Run Code Online (Sandbox Code Playgroud)

因此循环的使用似乎无关紧要.这留下了子串比较.

让我们举个例子:

. 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 |
    +------------------------------------+
Run Code Online (Sandbox Code Playgroud)

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

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


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

 gen byte OK = 0 
 levelsof A, local(Avals) 

 quietly foreach A of local Avals { 
     replace OK = 1 if strpos(ATC, `"`A'"') > 0 
 } 
Run Code Online (Sandbox Code Playgroud)

笔记:

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

  2. 您可能需要ifin限制levelsof.

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

  4. > 0可以省略,strpos()因为在逻辑比较中自动将其视为真.见这个FAQ.