Stata The Stata listserver
[Date Prev][Date Next][Thread Prev][Thread Next][Date index][Thread index]

Re: st: getting the quotes right


From   wgould@stata.com (William Gould)
To   statalist@hsphsun2.harvard.edu
Subject   Re: st: getting the quotes right
Date   Thu, 27 Jun 2002 08:38:45 -0500

Håkon Finne <Hakon.Finne@sintef.no> asks, 

> I need to generate a command that eventually has the following structure:
>
>       list v1 if v2=="alpha" | v2=="beta" | v2=="gamma"
>
> except [... it] is inside a loop, so it will be repeated with a different
> number of different conditional elements each time. So I try something like
> this [...]
>
>       . local buicks (make=="Buick Century" | make=="Buick Electra" | 
>                       make=="Buick Opel")
>
>       . local datsuns (make=="Datsun 200" | make=="Datsun 210")
>
>       . local vws (make=="VW Dasher" | make=="VW Rabbit" | 
>                    make=="VW Scirocco")
>
>       . local brands `buicks' `datsuns' `vws'
>
>       . foreach brand of local brands {
>       .        list price if `brand'
>       . }
>
> [...] this does not work. [...]

The solution to this problem is the addition of compound quotes.

Compound quotes look like `" and "' and they have the advantage that open
quotes can be old from close quote.  You need to use compound quotes when 
strings themselves contains (compound or simple) quotes.  Consider the 
string 

       a=="this" | b=="that"

Now imagine that, for some reason, you needed to put quotes around that (which
reason we will get to shortly).  Using simple quotes would not do because

       "a=="this" | b=="that""

could mean 

       "a=="    this   " | b=="     that  ""
       ^^^^^    ^^^^   ^^^^^^^^     ^^^^  ^^

and, in fact, that is exactly how Stata would interpret the string because, 
when you use " and ", the quotes are matched from left to right.

Compound quotes solve the problem

       `"a=="this" | b=="that""'
       ^^   [    ]      [    ]^^
       |                [    ] |
       |                       |
     open                     close

Compound quotes `" and "' solve the problem because they are like ( and );
they are easy to match.  Compound quotes solve the problem even if the inside
quotes were compound quotes.  Anyplace you use " and " you can use `" and "',
and sometimes you must use `" and "' to make your meaning clear.

Okay, with that long introduction, let's now consider Håkon's problem.  The
first thing Håkon does is define three macros, each of the form

        local <name> (make=="this" | make=="that" | ...)

That's fine, but notice that the three macros that Håkon defines each has
quotes in it.  I mention that because, should it turn out necessary that we 
quotes these macros, we must remember to use `" and "'.

In the next step, Håkon defines a composite macro containing all three, 

        local brands `buicks' `datsuns' `vws'

which is again fine, and Håkon finally steps across each using

and then tries to step across each using 

        foreach brand of local brands {

There is Håkon's problem.  Let us think about what is in `brands'.  It has 
the contents of `buicks', `datsuns', and `vws' all mashed together, one 
after the other:

        (make=="Buick Century" | make=="Buick Electra" | 
        make=="Buick Opel") (make=="Datsun 200" | make=="Datsun 210")
        (make=="VW Dasher" | make=="VW Rabbit" | make=="VW Scirocco")

Pretend what you see above is all on one line because, from Stata's point 
of view, it is.  Looking at that, how could Stata know that `"(make=="Buick
Century" | make=="Buick Electra" | make=="Buick Opel")"' is the first thing, 
`"(make=="Datsun 200" | make=="Datsun 210")"' is the second, and so on?
It could not.  There is nothing to separate one thing from the other.  So, 
when Stata saw 

        foreach brand of local brands {

it said the first thing is `"(make=="Buick)"', the second thing is
`"Century""', the third thing is "|", and so on, because -foreach- parses on
spaces and binds on quotes.

What Håkon needs to have in `brands' is
       
        `"(make=="Buick Century" | make=="Buick Electra" |
        make=="Buick Opel")"'  `"(make=="Datsun 200" | make=="Datsun 210")"'
        `"(make=="VW Dasher" | make=="VW Rabbit" | make=="VW Scirocco")"'

Notice my addition of the `" and "' around the first, second, and third
pieces, thus binding each together.  Now it is clear that the first thing is
`"(make=="Buick Century" | make=="Buick Electra" | make=="Buick Opel")"' is
the first thing, `"(make=="Datsun 200" | make=="Datsun 210")"' the second, and
so on.

I needed to use `" and "' rather than " and " because each of the pieces
themselves contain quotes.

Thus, rather than typing 

        local brands `buicks' `datsuns' `vws'

Håkon needed to type 

        local brands `"`buicks'"' `"`datsuns'"' `"`vws'"'

Do that, and Håkon's code will work.

Håkon could, if he wished, do away with `brands' altogether and rather than
typing 

        foreach brand of local brands {

type 

        foreach brands in `"`buicks'"' `"`datsuns'"' `"`vws'"' {

-- Bill
wgould@stata.com
*
*   For searches and help try:
*   http://www.stata.com/support/faqs/res/findit.html
*   http://www.stata.com/support/statalist/faq
*   http://www.ats.ucla.edu/stat/stata/



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