Frank
Frank

Reputation: 66819

Stata: check if any variables follow a naming pattern

I am about to create several temporary variables following the pattern tmp_*, and will drop (delete) them afterwards. I thought I would be clever and do...

ds tmp_*
assert ": word 1 of `r(varlist)'" == ""

** then I create and do stuff with tmp_bah and tmp_blah

drop tmp_*

That is, I wanted to perform a preliminary check to ensure that my final step does no damage to preexisting variables like tmp_thing_i_forgot_about.

Unsurprisingly, Stata did not oblige. The designers think my ds tmp_* is an error because it returns an empty result. I see that ds has several options, but none of them make it act like a normal search on the list of variable names (which would not whine upon a failed search).

I'm hoping someone can help me find the idiomatic way of approaching this problem.

Upvotes: 1

Views: 359

Answers (2)

Roberto Ferrer
Roberto Ferrer

Reputation: 11102

I'm not sure I understand exactly what you want to do, but I think you can use tempvars. A silly example:

clear 
set more off

sysuse auto
keep foreign

tempvar temp1

gen `temp1' = foreign - 100
gen usestemp = `temp1'^2

tempvar will fetch a safe name for your temporary variable and put it in local temp1 (in my example). Use it as you wish and after the program finishes, Stata takes care of dropping it.

You can create several at once: tempvar myvar1 myvar2 myvar3.

See help tempvar; and details in [P] macro.

Edit

As a side note, your assert statement will likely not check what you want. Consider some examples:

clear
set more off

set obs 1

gen tmp_1 = .
gen tmp_2 = .

ds tmp_*

* other versions
assert "`:word 1 of r(varlist)'" == "r(varlist)" // true
assert `:word 1 of r(varlist)' == "tmp_1 tmp_2"  // true
assert "`:word 1 of `=r(varlist)''" == "tmp_1"   // true

* your versions
assert ": word 1 of `r(varlist)'" == ": word 1 of tmp_1 tmp_2"  // true -->
assert ": word 1 of `r(varlist)'" == ""                         // ALWAYS false

I still find quotes a bit confusing, so I check very carefully when I have to use them; just to make sure the expression evaluates to what it's supposed to.

Upvotes: 3

Nick Cox
Nick Cox

Reputation: 37183

You are correct. As the purpose of ds is to display variable names, it's considered an error if what you specify isn't a varlist. You could

 capture ds tmp_* 

and work conditionally on the error code. But I wouldn't do that.

First of all, it's a purpose of confirm to confirm whether something exists. That's much more direct.

Second, it's fine to try to generate a new variable but to be clear that this will produce an error if that exists.

Third, far and away the best method to create a new temporary variable is to use the tempvar mechanism of getting a new name and then follow that with generate. As @Roberto Ferrer has separately explained that, all I need to do is to underline that it's the way to go.

EDIT: ds has morphed in its history from a command whose original purpose was a very concise display of variable names to one whose main role is to find names of variables defined by some criterion (e.g. being string or having value labels or a date format): findname (Stata Journal/SSC) is in essence a further generalization of ds that makes that more explicit. Note that a simple describe will return r(111) if the names specified are not in use and that's a further direct test that can be useful.

Upvotes: 3

Related Questions