1
votes

I have a set of variables the list of which I have saved in a global macro so that I can use them in a function

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

The reason why they are saved in a macro is because the list will be in a loop and its content will change depending on the year.

What I need to do is to generate a dummy variable so that water_dummy == 1 if any of the variables in the macro list has the WATER classification. In Stata, I need to write

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

, which--ideally--should translate to

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)

But this did not work---the code executed without any errors but the dummy variable only contained 0s. I know that it is possible to invoke macros inside functions in Stata, but I have never tried it when the macro contains a whole list of conditions. Any thoughts?

2
"not working for me" is not an adequate problem report. What does Stata complain about, if it complains at all? Note that the maximum number of arguments for strings is 10, and you have more. See help inlist.Roberto Ferrer
If you didn't reach the limit of inlist, removing the double quotes should resolve the issue.Aspen Chen
@RobertoFerrer: my apologies. I clarified how it doesn't work. I missed the max restriction, thank you.PollPenn
Thanks for the clarification. You can find alternatives below.Roberto Ferrer

2 Answers

4
votes

With a literal string specified, which the double quotes in the generate statement insist on, then you are comparing text with text and the comparison is not with the data at all.

. 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 |
     +---------------------------------------+

The first comparison is equivalent to

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

which finds no match, as "water" is not matched by the (single!) other argument.

Macro references are certainly allowed within function or command calls: as each macro name is replaced by its contents before the syntax is checked, the function or command never even knows that a macro reference was ever used.

As @Aspen Chen concisely points out, omitting the double quotes gives what you want so long as the inlist() syntax remains legal.

2
votes

If your data structure is something like in the following example, you can try the egen function incss, from egenmore (ssc 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

Be aware it searches for substrings (see the result for the last example observation).

A solution with a loop achieving different results is:

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

list

Another solution involves reshape, but I'll leave it at that.