遍历使用 levelsof 生成的列表
Iterate over list produced with levelsof
下面的例子重现了我的问题。有一个字符串变量,它有多个值。我想创建一个全局列表并循环迭代它。但它不起作用。我试过几个版本都没有成功。这是示例代码:
webuse auto, clear
levelsof make // list of car makes
global MAKE r(levels) // save levels in global list
foreach i in $MAKE { // loop some command over saved list
sum if make == "`$MAKE'" // ERROR 198, invalid 'Concord'
}
使用“`$MAKE'”或 $MAKE 不会产生所需的输出。
知道我做错了什么吗?
通常,要使列表正常工作,它们应该保存为 A B C D [...]
。在我的例子中,levelsof
生成以下类型的列表:
di $MAKE
`"AMC Concord"' `"AMC Pacer"' `"AMC Spirit"' `"Audi 5000"' `"Audi Fox"' `"BMW 320i"' [...]
所以显然不是所需要的。但不确定如何获得我需要的东西。
这是一个解决方案。请注意,我使用的是 local
而不是 global
。区别仅在于范围。如果您需要引用跨 do-files 的值,请仅使用 global
。您可以删除下面的 display
行。
*Sysuse reads this data from disk, it comes with all Stata installations
sysuse auto, clear
*Use levelsof, and assign the returned r(levels) using a = to the local
levelsof make
local all_makes = r(levels)
*Loop over the local like this. Note that foreach creates a local, in this
*case called this_make that stores the elements in the local one per iteration
foreach this_make of local all_makes {
display "`this_make'"
sum if make == "`this_make'"
}
如果您需要全局,那么您只需将其更改为:
*Sysuse reads this data from disk, it comes with all Stata installations
sysuse auto, clear
*Use levelsof, and assign the returned r(levels) using a = to the global
levelsof make
global all_makes = r(levels)
*Loop over the global like this. Note that foreach creates a local, in this
*case called this_make that stores the elements in the global one per iteration
foreach this_make of global all_makes {
display "`this_make'"
sum if make == "`this_make'"
}
有一个很好的公认答案,但还有很多可以说的。例如参见 [=16=].
作为其原作者,我对 levelsof
持肯定态度,但出于特定目的,要遍历变量的级别,使用 egen, group()
和循环会更简洁该变量的整数水平。有关更多信息,请参阅刚刚链接的常见问题解答。原始问题中的示例就是一个很好的例子,因为循环不同的字符串值可能很棘手,需要使用双引号 " "
并注意空格等。
根本问题没有揭示,但额外的评论是强调 by:
及其兄弟命令,如 statsby
或本质上类似的命令,如来自 SSC 的 rangestat
,实际上是循环而不循环。
下面的例子重现了我的问题。有一个字符串变量,它有多个值。我想创建一个全局列表并循环迭代它。但它不起作用。我试过几个版本都没有成功。这是示例代码:
webuse auto, clear
levelsof make // list of car makes
global MAKE r(levels) // save levels in global list
foreach i in $MAKE { // loop some command over saved list
sum if make == "`$MAKE'" // ERROR 198, invalid 'Concord'
}
使用“`$MAKE'”或 $MAKE 不会产生所需的输出。
知道我做错了什么吗?
通常,要使列表正常工作,它们应该保存为 A B C D [...]
。在我的例子中,levelsof
生成以下类型的列表:
di $MAKE
`"AMC Concord"' `"AMC Pacer"' `"AMC Spirit"' `"Audi 5000"' `"Audi Fox"' `"BMW 320i"' [...]
所以显然不是所需要的。但不确定如何获得我需要的东西。
这是一个解决方案。请注意,我使用的是 local
而不是 global
。区别仅在于范围。如果您需要引用跨 do-files 的值,请仅使用 global
。您可以删除下面的 display
行。
*Sysuse reads this data from disk, it comes with all Stata installations
sysuse auto, clear
*Use levelsof, and assign the returned r(levels) using a = to the local
levelsof make
local all_makes = r(levels)
*Loop over the local like this. Note that foreach creates a local, in this
*case called this_make that stores the elements in the local one per iteration
foreach this_make of local all_makes {
display "`this_make'"
sum if make == "`this_make'"
}
如果您需要全局,那么您只需将其更改为:
*Sysuse reads this data from disk, it comes with all Stata installations
sysuse auto, clear
*Use levelsof, and assign the returned r(levels) using a = to the global
levelsof make
global all_makes = r(levels)
*Loop over the global like this. Note that foreach creates a local, in this
*case called this_make that stores the elements in the global one per iteration
foreach this_make of global all_makes {
display "`this_make'"
sum if make == "`this_make'"
}
有一个很好的公认答案,但还有很多可以说的。例如参见 [=16=].
作为其原作者,我对 levelsof
持肯定态度,但出于特定目的,要遍历变量的级别,使用 egen, group()
和循环会更简洁该变量的整数水平。有关更多信息,请参阅刚刚链接的常见问题解答。原始问题中的示例就是一个很好的例子,因为循环不同的字符串值可能很棘手,需要使用双引号 " "
并注意空格等。
根本问题没有揭示,但额外的评论是强调 by:
及其兄弟命令,如 statsby
或本质上类似的命令,如来自 SSC 的 rangestat
,实际上是循环而不循环。