【问题标题】:Referencing macro values by index按索引引用宏值
【发布时间】:2017-03-04 21:36:34
【问题描述】:

我将下面的宏定义为变量idvar1var2 的级别:

levelsof id, local(id_lev) sep(,)
levelsof var1, local(var1_lev) sep(,)
levelsof var2, local(var2_lev) sep(,)

我希望能够在foreachforval 循环期间通过它们的索引引用存储在这些宏中的级别值。我正在学习如何使用宏,所以我不确定这是否可行。

当我尝试访问上述任何宏的单个元素时,会显示宏的每个元素。例如,如果我displayid_lev 的第一个元素,则每个元素都显示为单个元素(并且,最后一个元素被列为我不理解的无效名称):

. di `id_lev'[1]
0524062407240824092601260226032604 invalid name
r(198);

此外,如果我尝试在循环中引用任何宏的元素(下面给出了我尝试过的示例),我会收到错误,即级别列表的第三个值是无效数字。

foreach i of numlist 1/10 {
    whatever `var1'[i] `var2'[i], gen(newvar)
}

forval i = 1/10 {
    local var1_ `: word `i' of `var1''
    local var2_ `: word `i' of `var2''
    whatever `var1_' `var2_', gen(newvar)
}

不能通过索引来引用宏的元素吗?

还是我错误地引用了索引值?


更新 1:

我已经完成了所有工作(谢谢),除了调整 William 对上面我的循环的回答中给出的 forval 循环,我试图在相同的索引值处访问两个变量的宏。

具体来说,我想同时调用var1var2 的第一个、第二个、...、最后一个元素,以便我可以在循环中使用这些元素来生成一个新变量。我如何调整 William 建议的 forval 循环来完成此操作?


更新 2:

我能够修改下面 William 给出的代码来创建功能循环:

levelsof id, clean local(id_lev)
macro list _id_lev
local nid_lev : word count `id_lev'

levelsof var1, local(var1_lev)
macro list _var1_lev
local nvar1_lev : word count `var1_lev'

levelsof var2, local(var2_lev)
macro list _var2_lev
local nvar2_lev : word count `var2_lev'

forval i = 1/`nid_lev' {

    local id : word `i' of `id_lev'
    macro list _id
    local v1 : word `i' of `var1_lev'
    macro list _v1
    local v2 : word `i' of `var2_lev'
    macro list _v2

    whatever `v1' `v2', gen(newvar)

}

【问题讨论】:

  • 宏是拥有单个值的单个实体。它们不是向量或数组,因此索引引用没有意义。 display 命令中的 [1] 是产生错误消息的原因。该命令显示宏内容,然后被尾随的[1] 所迷惑,这不是一个名称。
  • 我们需要一个可重现的示例,并且我们需要知道您要创建什么变量。几乎可以肯定,有一种更直接的方法可以使用宏或循环来创建它。坚持在levelsof 中用逗号分隔会使解析宏变得更加困难,因为Stata 中的“单词”是由空格分隔的那些项目。这可能至少是循环问题的一部分。
  • 代码将在循环中第二次失败,因为newvar 已经存在。 -- 除非无法解释的程序whatever 破坏了该变量。所以你没有展示功能代码。

标签: for-loop indexing foreach stata stata-macros


【解决方案1】:

正如我在对上一个问题的结束语中提到的那样,您将从仔细研究 Stata 用户指南 PDF 的第 18.3 节中受益。

sysuse auto, clear
tab rep78, missing
levelsof rep78, missing local(replvl)
macro list _replvl
local numlvl : word count `replvl'
macro list _numlvl
forval i = 1/`numlvl' {
    local level : word `i' of `replvl'
    macro list _level
    display `level'+1000
}

产量

. sysuse auto, clear
(1978 Automobile Data)

. tab rep78, missing

     Repair |
Record 1978 |      Freq.     Percent        Cum.
------------+-----------------------------------
          1 |          2        2.70        2.70
          2 |          8       10.81       13.51
          3 |         30       40.54       54.05
          4 |         18       24.32       78.38
          5 |         11       14.86       93.24
          . |          5        6.76      100.00
------------+-----------------------------------
      Total |         74      100.00

. levelsof rep78, missing local(replvl)
1 2 3 4 5 .

. macro list _replvl
_replvl:        1 2 3 4 5 .

. local numlvl : word count `replvl'

. macro list _numlvl
_numlvl:        6

. forval i = 1/`numlvl' {
  2.     local level : word `i' of `replvl'
  3.         macro list _level
  4.         display `level'+1000
  5. }
_level:         1
1001
_level:         2
1002
_level:         3
1003
_level:         4
1004
_level:         5
1005
_level:         .
.

【讨论】:

  • 感谢您的帮助@WilliamLisowski。我已经完成了所有工作,直到您在底部包含的forval 循环。它在您给出的示例中运行良好,但我试图同时在两个宏上完成一个循环。这就是为什么我最初的想法是将宏视为索引向量,我可以通过同时调用var1var2 的第一个、第二个、...元素来引用它。我已经更新了我在上面执行此操作的尝试,但无法使语法正常工作。
  • 我也可以提出一个新问题,因为这特别适用于循环,如果这样更合适的话。
猜你喜欢
  • 2016-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-11
  • 2018-11-24
  • 1970-01-01
相关资源
最近更新 更多