[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

From |
"Nick Cox" <n.j.cox@durham.ac.uk> |

To |
<statalist@hsphsun2.harvard.edu> |

Subject |
st: RE: if and if |

Date |
Thu, 13 Nov 2008 14:31:33 -0000 |

This business of the two -if-s has confused many people. (Incidentally, I think -cond()- is a red herring as far as this question is concerned. It is without doubt very useful, but it has no bearing on the matter.) But what Ashim wants is, I think, not "in between" at all. He wants what he calls Type 2 -- the -if- command -- to do the same as what he calls Type 1 -- the -if- qualifier -- when both are based on tests on variables. However, it doesn't, and no amount of hoping, wishing, pushing or shoving will make it so -- apart from one borderline exception. His query raises the question of why Stata has the two constructs if they are really identical. But they aren't. It often happens that people used to some construct in other languages would like to see Stata behave that way, and vice versa, but that's the way it is. If you go to users' meetings (e.g. today and tomorrow in San Francisco), you can confront the developers and say "Why is Stata designed like that?". Sometimes there is a compelling argument against one syntax and for another; sometimes the answer is "We had to make a choice, and we just liked that syntax". But no syntax can be based on users knowing that they mean one thing in one context and one thing in another. All syntaxes have to be based on the language implementation having only one interpretation of what is meant. I have got to say, however, that the Stata documentation is not 100% innocent here. If you look at -help ifcmd- it gives among other details ================= Typical use: Example 3 program ... ... if x==1 local word "one" else if x==2 local word "two" else if x==3 local word "three" else if x==4 local word "four" else local word "big" ... end ================== But this example is _only_ good programming style if -x- is a scalar. (Arguably not even then, as a temporary name would be preferable.) And that is not explained, or (to me) self-evident. Also, the fact that (again, for a variable x) if x == 1 ... will be taken as if x[1] == 1 ... is not explained in the help, although it is in [P] -if- and the FAQ cited earlier in this thread. I think several people would find out about this matter earlier and easier if the point were made in the help. The borderline exception is thus that for a variable x if x == 1 ... is exactly equivalent to ... if x == 1 if and only if you have a single-observation dataset. There are languages that support something like if x == 1 ... as equivalent to ... if x == 1 -- doesn't SAS support something similar -- but that is in a context that implies a loop over observations. Stata's way of supporting loops over observations (think of the ways that -generate- and -replace- work) is more usually implicit. As Ashim pointed out, Stata offers a concise alternative to replace j=2 if k==2 replace m=2 if k==2 replace n=2 if k==2 It is foreach v of var j m n { replace `v' = 2 if k == 2 } (Ashim's own code here is illegal, by virtue of his omitting "var".) Alternatively, you can go foreach v in j m n { Short of Stata re-inventing itself as an ultra-terse language like APL or J either seems to me about as concise as anyone might want. I really don't understand why Ashim wants a "better way". What could be better, or how is this lacking? Nick n.j.cox@durham.ac.uk Ashim Kapoor I realize that there are 2 kinds if's in Stata. Type 1 : would be something like replace j = 2 if k==2 here the replace in j would happen ONLY in the corresponding observation of k. THIS IS WHAT I WANT. Type 2 : the programming if something like local j if `j'==2 { do something. } ************************************************************** I guess I want to do something which is in between the above 2. I want to say the following : -- replace j=2 if k==2 replace m=2 if k==2 replace n=2 if k==2 in ONE shot. so I try : - ************************************** Block A if k==2 { replace j=2 replace m=2 replace n=2 } ********************************************* This does not work. Because k==2 would mean k==2 in ALL observations. While I mean to say make j / m / n = 2 in those observations where k is 2. How do I do this in a quick manner in Block A ? I understand that I can always do :- foreach var of j m n { replace `var'=2 if k==2 } But is there a better way ? The reason I want this is the following : - I want if k==2 { replace j=1 replace m=5 replace n=89 } so the above method fails as I do not have the SAME value 2 to be put in each of j / m /n. Any slick way of doing this ? * * 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/

**Follow-Ups**:**Re: st: RE: if and if***From:*"Ashim Kapoor" <ashimkapoor@gmail.com>

**References**:**st: if and if***From:*"Ashim Kapoor" <ashimkapoor@gmail.com>

- Prev by Date:
**RE: st: Writing graphs to the log file** - Next by Date:
**Re: st: Stata 10 MP4 crashing** - Previous by thread:
**Re: st: R: if and if** - Next by thread:
**Re: st: RE: if and if** - Index(es):

© Copyright 1996–2019 StataCorp LLC | Terms of use | Privacy | Contact us | What's new | Site index |