Sergiy et al.--
I wouldn't worry about macros since they will be evaluated, but I am
probably missing some other problems. Here was my imperfect first cut:
clear all
prog shvars
syntax [if]
tempname x
loc if:subinstr loc if "c(" "`x'", all
loc if:subinstr loc if "r(" "`x'", all
loc if:subinstr loc if "e(" "`x'", all
tokenize `"`if'"', parse(" !~^+-*/=<>]()&|")
while `"`1'"'!="" {
cap unab v: `1'
if _rc==0 loc varlist "`varlist' `v'"
mac sh
}
di "`varlist'"
end
sysuse auto
su mpg
g meanvar=1
shvars if mpg==r(mean)&(di==_pi|gear_r==c(pi))
Here is one headache:
. shvars if mpg==r(mean)&(di==_pi|gear_r==c(pi))&floor(f)==0
mpg displacement gear_ratio
. shvars if mpg==r(mean)&(di==_pi|gear_r==c(pi))&trunc(f)==0
mpg displacement gear_ratio
. shvars if mpg==r(mean)&(di==_pi|gear_r==c(pi))&reverse(make)==""
mpg displacement gear_ratio
I.e. it is not good enough to strip out r( and c( and e( since these
can be the end of a function.
Here is one fix, but still not complete (no mention of factor variables yet):
clear all
prog shvars
syntax [if]
tempname x
foreach h in c e r {
foreach a in `c(alpha)' {
loc if:subinstr loc if "`a'`h'(" "`a'x(", all
}
loc if:subinstr loc if "`h'(" "`x'", all
}
tokenize `"`if'"', parse(" !~^+-*/=<>]()&|")
while `"`1'"'!="" {
cap unab v: `1'
if _rc==0 loc varlist "`varlist' `v'"
mac sh
}
di "`varlist'"
end
sysuse auto
su mpg
g meanvar=1
shvars if mpg==r(mean)&(di==_pi|gear_r==c(pi))
shvars if mpg==r(mean)&(di==_pi|gear_r==c(pi))&floor(f)==0
On Wed, Aug 12, 2009 at 4:48 PM, Jeph Herrin<[email protected]> wrote:
> Another consideration is that an -if- condition can
> refer to a scalar
>
> ********************
> program foo
> syntax [if]
> di "`if'"
> end
> ********************
> . clear, all
> . scalar cond=1
> . foo if cond==1
> if cond==1
>
> not to mention locals and globals.
>
> Good luck!
>
> Jeph
>
>
>
>
> Nick Cox wrote:
>>
>> I don't know a neat way to do this. Among other problems, a complete
>> solution would need to consider that
>> 1. An -if- condition might contain temporary variable names, too. Your
>> logic seems to hold despite that.
>> 2. An -if- condition could refer to r(), e(), c() and Stata matrices.
>> Your logic might need some modification there.
>> Nick [email protected]
>> Sergiy Radyakin
>>
>> how do I get the list of variables used in an if-condition passed to
>> my Stata program?
>> obviously all sorts of logical expressions and functions are permitted
>> in the if-condition.
>>
>>
>> program foobar
>> syntax [if]
>>
>> // ... determine which vars are used in the if-condition and put
>> them in var_list ...
>> // ... compute something ...
>>
>> end
>>
>>
>> I am looking for an elegant solution, the one that would not involve,
>> say, dropping vars one
>> by one and checking if the expression is still computable.
>>
>> One solution is to replace all the ! ~ ^ + - * / = < > ] and ) to
>> spaces, then look at the tokens left.
>> Those with ( immediately following are function names, those with [ or
>> a space immidetely
>> following are variables. (and we can use -capture confirm variable- to
>> check that).
>>
>> Is there any problem with such an approach? (e.g. factor variables in
>> Stata 11?)
>> Is there a better (or a standard/existing) approach to the problem?
*
* For searches and help try:
* http://www.stata.com/help.cgi?search
* http://www.stata.com/support/statalist/faq
* http://www.ats.ucla.edu/stat/stata/