Stata在宏上的行为,不同的输出

Jor*_*man 2 statistics stata

我有一个我在stata宏中创建的手册列表,类似于

global list1 "a b c d"
Run Code Online (Sandbox Code Playgroud)

我后来用类似的东西迭代

foreach name in $list1 {
action
}
Run Code Online (Sandbox Code Playgroud)

我试图将其更改为数据库驱动列表,因为列表变得越来越大并且快速变化,我使用以下命令创建一个新的$ list1

odbc load listitems=items, exec("SELECT items  from my_table")  
levelsof listitems
global list1=r(levels)
Run Code Online (Sandbox Code Playgroud)

每个项目都是相同的,但是这个列表似乎有所不同,当我有太多项目时,它会在for循环中出现错误

{ required
r(100);
Run Code Online (Sandbox Code Playgroud)

此外,当我只运行listitems级别时,我得到输出

`"a"' `"b"' `"c"' `"d"' 
Run Code Online (Sandbox Code Playgroud)

看起来与其他宏看起来有点不同.

我已经坚持了一段时间.同样,只有当项目数量变大(超过15)时才会失败,任何帮助都会非常感激.

小智 7

解决方案1:

levelsof listitems, clean local(list1)
foreach name of local list1 {
    ...action with `name'...
}
Run Code Online (Sandbox Code Playgroud)

解决方案2:

levelsof listitems, clean
global list1 `r(levels)'
foreach name of global list1 {
    ...action with `name'...
}
Run Code Online (Sandbox Code Playgroud)

说明:

当你输入

foreach name in $list1 {
Run Code Online (Sandbox Code Playgroud)

然后在Stata看到它之前,$ list1中的任何内容都被替换为内联.如果全局宏列表1包含很长的事物列表,那么Stata会看到

foreach name in a b c d e .... very long list of things here ... {
Run Code Online (Sandbox Code Playgroud)

告诉Stata你有一个全局或本地宏中的事物列表,并且你想要循环这些事情是更有效的.您不必在命令行上展开它们.那是什么

foreach name of local list1 {
Run Code Online (Sandbox Code Playgroud)

foreach name of global list1 {
Run Code Online (Sandbox Code Playgroud)

是给.你可以在-achp foreach-中阅读foreach的其他功能.

另外,您最初编码

levelsof listitems
global list1=r(levels)
Run Code Online (Sandbox Code Playgroud)

而且你注意到你看到了

`"a"' `"b"' `"c"' ...
Run Code Online (Sandbox Code Playgroud)

结果是.这些是Stata所说的"复合引用"字符串.复合引号字符串可让您有效地嵌套引用的内容.所以,你可以有类似的东西

`"This is a string with `"another quoted string"' inside it"'
Run Code Online (Sandbox Code Playgroud)

你说你不需要它,所以你可以使用levelsof的"clean"选项来不引用结果.(有关此选项的更多信息,请参阅-help levelsof.)此外,您之后将levelsof的返回结果(在r(级别)中)分配给全局宏.事实证明-levelsof-实际上有一个名为-local()的选项 - 您可以在其中指定本地(非全局)宏的名称以直接输入结果.因此,您只需键入

levelsof listitems, clean local(list1)
Run Code Online (Sandbox Code Playgroud)

省略复合引号并直接将结果放在名为list1的本地宏中.

最后,如果由于某种原因你不想使用那个local()选项并希望坚持将列表放在一个全局宏中,你应该编码

global list1 `r(levels)'
Run Code Online (Sandbox Code Playgroud)

而不是

global list1=r(levels)
Run Code Online (Sandbox Code Playgroud)

区别在于后者将r(级别)视为一个函数,并通过Stata的字符串表达式解析器运行它.在Stata中,字符串(字符串,而不是包含字符串的宏)的限制为244个字符.另一方面,包含字符串的宏可以包含数千个字符.所以,如果r(级别)中有超过244个字符,那么

global list1=r(levels)
Run Code Online (Sandbox Code Playgroud)

最终将以244个字符截断存储在list1中的结果.

当你改为代码时

global list1 `r(levels)'
Run Code Online (Sandbox Code Playgroud)

然后在执行命令之前,内联扩展r(级别)的内容.所以,Stata看到了

global list1 a b c d e ... very long list ... x y z
Run Code Online (Sandbox Code Playgroud)

并且宏名称(list1)之后的所有内容都被复制到该宏名称中,无论它有多长.