There is a series of regressions I want to run, and in each regression, I decide if I want a covariate or not. So for example, let's say I have a local macro with 10 covariates:
local covariates "`N' age `N' sex `N' age2 `N' job job2 `N'"
I want 10 regressions, each with one covariate in order as listed. However, the `N'
terms are placeholders meant to show that I don't want a covariate in that regression. So when running the regressions, it looks something like:
forval i=1/10 {
local cov `: word `i' of `covariates''
if "`cov'" != "N" {
reg y x `cov'
}
else {
reg y x
}
}
where y
is an outcome, and x
is another covariate that's included in every regression.
My issue is that Stata does not recognize the `N'
placeholders. More specifically, it seems like the if "`cov'" != "N"
condition filters out the placeholder variables from going to the reg y x `cov'
step, but they don't go to the else
condition to run reg y x
. After some debugging, it seems like Stata simply doesn't realize that the length of covariates
is 10: when I check the length of the macro, it returns 5, and when I print each term in the macro, it only returns 5 values. Since Stata thinks the length of the macro is 5, then it breaks once the forval
loop hits i=6
. Hence I only get 5 regressions of the form reg y x `cov'
.
So, is there a clean way to include some sort of placeholder such that Stata will recognize the length of the macro, and thus run all 10 regressions?
This works for me:
sysuse auto, clear
local cov weight price N turn
foreach v of local cov {
if "`v'" == "N" regress mpg i.foreign
else regress mpg i.foreign `v'
}
You didn't provide a complete reproducible example. But your local macro cov
contains 10 words if and only if when it is defined there is a local macro N
defined and visible that contains one word.
Further, only if local macro N
contains the word "N"
will your code work as desired.
Indeed, it is hard to see why you use a local macro reference there at all.
It is not illegal to refer to a local macro that doesn't exist, but it will be evaluated as an empty string, and the consequence of that may be not what you want, as here. Here "doesn't exist" means previously defined within the same program, do-file or chunk of code in do-file editor.
Note that foreach
provides a direct route to looping over the words of a local macro.
A simple if trite comment is that writing down ten statements for the ten regressions you do want will give code that is easier to write and easier to read....