【问题标题】:Is it possible to invoke a global macro inside a function in Stata?是否可以在 Stata 的函数内调用全局宏?
【发布时间】:2015-08-18 21:08:04
【问题描述】:

我有一组变量,我将它们的列表保存在全局宏中,以便我可以在函数中使用它们

global inlist_cond "amz2002ras_clss, amz2003ras_clss, amz2004ras_clss, amz2005ras_clss, amz2006ras_clss, amz2007ras_clss, amz2008ras_clss, amz2009ras_clss, amz2010ras_clss, amz2011ras_clss"

之所以将它们保存在宏中是因为列表将处于循环状态,并且其内容会根据年份而变化。

我需要做的是生成一个虚拟变量,如果宏列表中的任何变量具有 WATER 分类,则 water_dummy == 1。在Stata中,我需要写

gen water_dummy = inlist("WATER", "$inlist_cond")

,理想情况下应该转换为

gen water_dummy = inlist("WATER", amz2002ras_clss, amz2003ras_clss, amz2004ras_clss, amz2005ras_clss, amz2006ras_clss, amz2007ras_clss, amz2008ras_clss, amz2009ras_clss, amz2010ras_clss, amz2011ras_clss)

但这不起作用——执行的代码没有任何错误,但虚拟变量只包含 0。我知道可以在 Stata 中的函数内部调用宏,但是当宏包含完整的条件列表时,我从未尝试过。有什么想法吗?

【问题讨论】:

  • “不适合我”不是一个充分的问题报告。 Stata 抱怨什么,如果它抱怨的话?请注意,字符串的最大参数数量为 10,而且您还有更多。见help inlist
  • 如果您没有达到inlist 的限制,删除双引号应该可以解决问题。
  • @RobertoFerrer:我很抱歉。我澄清了它是如何不起作用的。我错过了最大限制,谢谢。
  • 感谢您的澄清。您可以在下面找到替代方案。

标签: stata


【解决方案1】:

使用指定的文字字符串,generate 语句中的双引号坚持,那么您将文本与文本进行比较,并且根本不与数据进行比较。

. clear

. set obs 1
number of observations (_N) was 0, now 1

. gen a = "water" 

. gen b = "wine" 

. gen c = "beer" 

. global myvars "a,b,c"

. gen found1 = inlist("water", "$myvars") 

. gen found2 = inlist("water", $myvars) 

. list 

     +---------------------------------------+
     |     a      b      c   found1   found2 |
     |---------------------------------------|
  1. | water   wine   beer        0        1 |
     +---------------------------------------+

第一个比较等价于

. di inlist("water", "a,b,c")
0

找不到匹配项,因为 "water" 与(单个!)其他参数不匹配。

在函数或命令调用中当然允许宏引用:由于在检查语法之前每个宏名称都被其内容替换,因此函数或命令甚至都不知道曾经使用过宏引用。

正如@Aspen Chen 简洁指出的那样,只要inlist() 语法仍然合法,省略双引号就可以得到你想要的。

【讨论】:

    【解决方案2】:

    如果你的数据结构类似于下面的例子,你可以试试egen函数incss,来自egenmoressc install egenmore):

    clear
    set more off
    
    input ///
    str15(amz2009 amz2010)
    "water" "juice"
    "milk" "water"
    "lemonade" "wine"
    "water & beer" "tea"
    end
    
    list
    
    egen watindic = incss(amz*), sub(water)
    
    list
    

    请注意它会搜索 子字符串(请参阅最后一个示例观察的结果)。

    使用循环实现不同结果的解决方案是:

    gen watindic2 = 0
    forvalues i = 2009/2010 {
        replace watindic2 = 1 if amz`i' == "water"
    }
    
    list
    

    另一种解决方案涉及reshape,但我会留在那里。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-26
      • 2011-10-28
      • 2011-09-14
      • 1970-01-01
      • 1970-01-01
      • 2015-02-23
      • 1970-01-01
      相关资源
      最近更新 更多