我有一个我在stata宏中创建的手册列表,类似于
global list1 "a b c d"
我后来用
之类的东西进行迭代foreach name in $list1 {
action
}
我正在尝试将其更改为数据库驱动列表,因为列表变得越来越大并且快速变化,我使用以下命令创建一个新的$ list1
odbc load listitems=items, exec("SELECT items from my_table")
levelsof listitems
global list1=r(levels)
每个上的项目是相同的,但是这个列表似乎有所不同,当我有太多项目时,它会在for循环中出现错误
{ required
r(100);
另外,当我只运行listitems的级别时,我得到了输出
`"a"' `"b"' `"c"' `"d"'
与其他宏看起来有点不同。
我已经坚持了一段时间。再次,只有当项目数量变大(超过15)时才会失败,任何帮助都会非常受欢迎。
答案 0 :(得分:7)
解决方案1:
levelsof listitems, clean local(list1)
foreach name of local list1 {
...action with `name'...
}
解决方案2:
levelsof listitems, clean
global list1 `r(levels)'
foreach name of global list1 {
...action with `name'...
}
说明:
键入
时foreach name in $list1 {
然后,在Stata看到之前,$ list1中的任何内容都会被内联替换。如果全局宏列表1包含很长的事物列表,那么Stata将会看到
foreach name in a b c d e .... very long list of things here ... {
告诉Stata你有一个全局或本地宏中的事物列表,并且你想要循环这些事情是更有效的。您不必在命令行上展开它们。这就是
foreach name of local list1 {
和
foreach name of global list1 {
是为了。你可以在-help foreach中了解foreach的其他功能 - 。
另外,您最初编码
levelsof listitems
global list1=r(levels)
你注意到你看到了
`"a"' `"b"' `"c"' ...
结果是。这些是Stata所说的“复合引用”字符串。复合引号字符串可让您有效地嵌套引用的内容。所以,你可以有像
这样的东西`"This is a string with `"another quoted string"' inside it"'
你说你不需要那样,所以你可以使用levelsof的“clean”选项来不引用结果。 (有关此选项的更多信息,请参阅-help levelsof。)此外,您之后将levelsof的返回结果(在r(级别)中)分配给全局宏。事实证明-levelsof-实际上有一个名为-local()的选项 - 您可以在其中指定本地(非全局)宏的名称以直接输入结果。因此,您只需键入
levelsof listitems, clean local(list1)
既省略复合引号又直接将结果放在名为list1的本地宏中。
最后,如果由于某种原因你不想使用那个local()选项并希望坚持将列表放在一个全局宏中,你应该编码
global list1 `r(levels)'
而不是
global list1=r(levels)
区别在于后者将r(级别)视为一个函数,并通过Stata的字符串表达式解析器运行它。在Stata中,字符串(字符串,而不是包含字符串的宏)的限制为244个字符。另一方面,包含字符串的宏可以包含数千个字符。所以,如果r(级别)中有超过244个字符,那么
global list1=r(levels)
最终将以244个字符截断存储在list1中的结果。
当您改为编码
时global list1 `r(levels)'
然后在执行命令之前在线扩展r(级别)的内容。所以,Stata认为
global list1 a b c d e ... very long list ... x y z
将宏名称(list1)之后的所有内容复制到该宏名称中,无论它有多长。