我刚开始学习Stata而且我很难过。
我的问题是:我有两个不同的变量,ATC
和A
,其中A
可能是ATC
的子字符串。
现在,我想标记A
是ATC
的子字符串OK = 1
的所有观察结果。
我使用一个简单的嵌套循环尝试了这个:
foreach x in ATC {
foreach j in A {
replace OK = 1 if strpos(`x',`j')!=0
}
}
但是,每当我运行此循环时,即使应该有足够的内容,也不会进行任何更改。
我觉得我应该给出一个索引来指定哪个OK
正在被更改(属于ATC
/ x的那个),但我不知道如何做到这一点。这可能非常简单,但我已经挣扎了一段时间。
我应该澄清一下:我的A
列表与主列表分开(只是附加到它),并且只包含用于标识我想要的ATC
的唯一键。所以我有~120 A
- 键和几百万ATC
个键。我想要做的是迭代每个ATC
密钥的每个A
密钥,并标记那些符合ATC
的{{1}}密钥。
这意味着我没有(A
,ATC
,A
)的完整元组,而是分开不同大小的列表。
例如:我有
OK
并希望结果ATC OK A
ABCD 0 .
EFGH 0 .
... ... ...
. . AB
. . ET
"ABCD"
标记为OK
而1
仍为"EFGH"
。
答案 0 :(得分:5)
我们可以将您的问题分为两部分。你的标题意味着循环问题,但你的循环只相当于
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
}
注意:
指定byte
会减少存储空间。
if
可能需要in
或levelsof
限制。
quietly
会删除有关已更改值的消息。调试时,通常最好省略。
> 0
可以省略,因为来自strpos()
的肯定结果会在逻辑比较中自动视为true。见this FAQ。