Reputation: 66819
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
Reputation: 11102
I'm not sure I understand exactly what you want to do, but I think you can use tempvar
s. 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.
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
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