Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Numbers as strings in local macro

    How to store in local macro a list of fractions. For example:
    Code:
    local ratios ""1487/1141" "791/620""
    local ratio : word 1 of `ratios'
    display `ratio'
    displays the result of diving 1487 by 1141. But what I want in `ratio' is the string "1487/1141"
    Any suggestions?

  • #2
    If you use double quotes around the macro, it's evaluated as a string. If you don't, it's evaluated as an expression:

    Code:
    . display `ratio'
    1.3032428
    
    . display "`ratio'"
    1487/1141

    Comment


    • #3
      Thanks Ali. So simple :-)

      Comment


      • #4
        The overarching principle Ali has demonstrated is that the display command goes to some length to evaluate any expressions in what it is asked to display, and in defining macros, any surrounding pair of quotation marks are removed.

        The macro list command presents the contents of macros with no attempt at interpretation, which can be convenient when testing code. In this case, it shows that after defining ratio, the surrounding quotation marks have been stripped off, just as the outermost pair were stripped off in the definition of ratios, which is why `ratio' was not treated as a string as you had hoped it would be.
        Code:
        . local ratios ""1487/1141" "791/620""
        
        . macro list _ratios
        _ratios:        "1487/1141" "791/620"
        
        . local ratio : word 1 of `ratios'
        
        . macro list _ratio
        _ratio:         1487/1141
        
        . display `ratio'
        1.3032428
        
        . display "`ratio'"
        1487/1141
        In fact, all of the quotation marks in the definition of ratios can be omitted without affecting these results.
        Code:
         local ratios 1487/1141 791/620
        
        . macro list _ratios
        _ratios:        1487/1141 791/620
        
        . local ratio : word 1 of `ratios'
        
        . macro list _ratio
        _ratio:         1487/1141
        
        . display `ratio'
        1.3032428
        
        . display "`ratio'"
        1487/1141

        Comment


        • #5
          Note:
          Code:
          local x1 = 2 + 7
          local x2 "2 + 7"
          di 2*`x1' " is unequal to " 2*`x2'
          Code:
          . di 2*`x1' " is unequal to " 2*`x2'
          18 is unequal to 11

          Comment


          • #6
            Post #5 makes the important point that defining a macro using an equal sign forces the evaluation of any expression at the time the macro is defined.
            Code:
            . local x1 = 2 + 7
            
            . local x2 "2 + 7"
            
            . local x3 2 + 7
            
            . macro list _x1 _x2 _x3
            _x1:            9
            _x2:            2 + 7
            _x3:            2 + 7
            
            . di 2*`x1'
            18
            
            . di 2*`x2'
            11
            
            . di 2*`x3'
            11
            
            . di 2*(`x3')
            18

            Comment


            • #7
              Where does "11" come from in this?
              Code:
              local x2 "2 + 7"
              .display 2*`x2'
              11

              Comment


              • #8
                Since 2+7 is placed in quotes, the expression 2+7 is not evaluated. Rather local macro x2 contains the string 2+7. So the display command sees:

                Code:
                display 2*2 + 7
                and since multiplication precedes addition when evaluating expresions, this evaluates to 4 + 7 which, in turn, evaluates to 11.

                If you want to get 18 as the answer you would have to do it as:
                Code:
                display 2*(`x2')
                or, you could build the parentheses directly into x2 first:

                Code:
                local x2 "(2 + 7)"
                display `*`x2'
                Added: Actually, I erred in attributing the 11 result to the wrapping of 2 + 7 in quotes. Even without the quotes, we still get 11 because the -local- command does not evaluate the expressions fed to it. It stores them as strings, even if there are no quotes around them.

                If you want to force evaluation of an expression in the -local- command, you can do that with the = operator:

                Code:
                . local x2 = 2 + 7
                
                . display 2*`x2'
                18
                Last edited by Clyde Schechter; 23 May 2021, 15:58.

                Comment


                • #9
                  Code:
                  2*2+7

                  Comment


                  • #10
                    Thank you all for your clear explanations. It might be just me, but the local macro stuff, although most useful, is not very intuitive.

                    Comment


                    • #11
                      If it is not intuitive this is because you did not expect that there is the overriding rule that an equal sign in the context of a local macro forces the expression to be evaluated before it is stored in the local macro. What is stored is still a string (either the result from 2+7, which is "9" if preceded by =, or the string "2+7" if not preceded by =). That the equal sign in the context of a macro serves to evaluate the expression is very useful, for example in a context where Stata expects a number and cannot evaluate the expression "by itself". Examples:
                      Code:
                      clear*
                      cls
                      
                      local x 2 + 7
                      di 2*`x'                                      // Stata sees "di 2*2+7"
                      di 2*`=`x''                                   // Stata sees "di 2*9"
                      
                      cap noi: cii prop 100 9                       // Stata sees "cii prop 100 9"
                      cap noi: cii prop 100 `x'                     // Stata sees "cii prop 100 2 + 7"
                      cap noi: cii prop 100 `=`x''                  // Stata sees "cii prop 100 9"
                      cap noi: cii prop 100 `=`x'' , level(95)      // Stata sees "cii prop 100 9, level(95)"
                      cap noi: cii prop 100 `=`x'' , level(90+5)    // Stata sees "cii prop 100 9, level(9+5)"
                      cap noi: cii prop 100 `=`x'' , level(`=90+5') // Stata sees "cii prop 100 9, level(95)"
                      Code:
                      . di 2*`x'                                      // Stata sees "di 2*2+7"
                      11
                      
                      . di 2*`=`x''                                   // Stata sees "di 2*9"
                      18
                      
                      .
                      . cap noi: cii prop 100 9                       // Stata sees "cii prop 100 9"
                      
                                                                               -- Binomial Exact --
                          Variable |        Obs  Proportion    Std. Err.       [95% Conf. Interval]
                      -------------+---------------------------------------------------------------
                                   |        100         .09    .0286182        .0419836    .1639823
                      
                      . cap noi: cii prop 100 `x'                     // Stata sees "cii prop 100 2 + 7"
                      you must specify 2 arguments with cii proportions: #obs and #succ
                      
                      . cap noi: cii prop 100 `=`x''                  // Stata sees "cii prop 100 9"
                      
                                                                               -- Binomial Exact --
                          Variable |        Obs  Proportion    Std. Err.       [95% Conf. Interval]
                      -------------+---------------------------------------------------------------
                                   |        100         .09    .0286182        .0419836    .1639823
                      
                      . cap noi: cii prop 100 `=`x'' , level(95)      // Stata sees "cii prop 100 9, level(95)"
                      
                                                                               -- Binomial Exact --
                          Variable |        Obs  Proportion    Std. Err.       [95% Conf. Interval]
                      -------------+---------------------------------------------------------------
                                   |        100         .09    .0286182        .0419836    .1639823
                      
                      . cap noi: cii prop 100 `=`x'' , level(90+5)    // Stata sees "cii prop 100 9, level(9+5)"
                      90+5 found where number expected
                      
                      . cap noi: cii prop 100 `=`x'' , level(`=90+5') // Stata sees "cii prop 100 9, level(95)"
                      
                                                                               -- Binomial Exact --
                          Variable |        Obs  Proportion    Std. Err.       [95% Conf. Interval]
                      -------------+---------------------------------------------------------------
                                   |        100         .09    .0286182        .0419836    .1639823

                      Comment

                      Working...
                      X