Announcement

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

  • Displaying local macros in Graph Bar notes

    Dear list,

    I'm in the process of creating graphs for a regular report and I'd like to include a note which has the point estimate and 95% confidence intervals from the corresponding logistic regression. I've been able to extract those from the output matrix to store as a scalar. I've then converted those scalars to local macros which display the values as intended outside of a graph, but once inserted into the notes for the bar graph, only the name of the local macro displays in the notes although the rest of the graph displays correctly. I've tried double quotes, no quotes, and a few others which don't seem to work. Any help on getting these values to display properly is much appreciated - an approximation the code I'm working with is below.

    clogit x y if b==1, group(group)
    scalar point = round(exp(_b[y]), 0.01)
    local point point
    scalar ll = round(el(r(table),5,1), 0.01)
    local ll ll
    scalar ul = round(el(r(table),6,1), 0.01)
    local ul ul

    graph bar (mean) x if b==1, over(y) by(group, ///
    compact total ///
    title("Example title graph") ///
    subtitle("by group") ///
    note("OR `local', 95% CI `ul' - `ll' " )) ///
    ylabel(0 0.2 "20" .4 "40" .6 "60" .8 "80)

    Thanks!

    Sam
    Last edited by Samuel Aitken; 06 Apr 2016, 16:34.

  • #2
    On the assumption that you want to understand what's wrong:

    1. When you write (e.g.)

    Code:
    local ll ul
    you are defining the local macro with name ll to be the string "ul" , which is not what you want. Your other local definitions have the same flavour, except that the last is a typo, as you mean to put the upper limit in a local, not the lower limit twice. You would need an assignment for the way you did it using an equals sign.

    2. round() is a numeric operation which is not equivalent to formatting to a particular number of decimal places: the effects may look similar, but the method is fragile. For why, which can be a long story, search for items on precision.

    3. The scalars are not needed here. Putting stuff into a scalar and then putting the scalar into a local is like putting stuff in a red box, taking it out and then putting it into a blue box. You can miss out the red box. There is no syntax error: it is just that the code can be shortened and simplified.

    4. In your graph command you invoke a local macro named local which is never defined. That looks like just the wrong name: I think you meant point

    5. A double quote is missing on the last command line.

    I can't test this without example data, which I am too lazy to invent, but I think it's closer to what you want:


    Code:
    clogit x y if b==1, group(group)
    local point : di %2.1f  exp(_b[y])
    local ll : di %3.2f  el(r(table),5,1)
    local ul : di %3.2f el(r(table),6,1)
    
    graph bar (mean) x if b==1, over(y) by(group,  compact total ///
    title("Example title graph") subtitle("by group") note("OR `point', 95% CI `ul' - `ll'" )) ///
    ylabel(0 0.2 "20" .4 "40" .6 "60" .8 "80")

    Comment


    • #3
      Thank you! This worked perfectly - it must have been a typo that I had overlooked that seemed to be resulting in the error. Points 1 and 4 were definitely typos that came up as I translated from the data to generic terms, so thank you for pointing those out. I also appreciate the information on the round function and the use of scalars / macros...that will be very helpful as time goes on.

      Thanks again!

      Sam

      Comment


      • #4
        Good, but let's go back to your original comment that "only the name of the local macro displays in the notes".

        Omitting the equals sign was the source of that problem. Typo or not, that crossed a bridge between copying to a macro and evaluating an expression, which are different things.

        This points up the difference:

        Code:
        . scalar pi = _pi
        
        . local pi pi
        
        . di "`pi'"
        pi
        
        . local pi = pi
        
        . di "`pi'"
        3.141592653589793
        The first definition of the local just copies a string literally -- whether that string is in use as a name is neither here nor there -- and Stata evaluates nothing. The second, with the equals sign, causes an evaluation.

        Incidentally,

        Code:
        local pi = scalar(pi)
        would be safer code as scalar names belong in the same space as variable names, and if Stata saw a variable whose name was, or began with, pi then that would be used. That's a documented pitfall but easy to miss.

        For your problem, I've already advised that scalars can be avoided, but here I am sticking close to the kind of thing you were doing to try to explain what is going on.

        Comment


        • #5
          Thanks again for the information. It seemed as if this command:

          display local

          Had been working (i.e., it was showing the stored value of the corresponding scalar) outside of the graph, but then switched to the macro text within. Was that just an artifact of me running parts of the code when I was troubleshooting?

          Comment


          • #6
            If you had defined the corresponding scalar earlier, and there was no clash with variable names, then the display command would have shown its value just like this code does:

            Code:
            . scalar local = exp(1)
            
            . display local
            2.7182818
            That's not a puzzle; it's a logical consequence of what you did. But I don't understand in what sense it would then seem to switch to the macro text within. There is no text within that scalar; the scalar holds a numeric value.

            If you defined and then referred to a local macro, then you'd expect to see its text contents.

            Nothing stops you having scalars and locals with the same name, but there is no inherent connection between them. If you happened to define a local with the contents of a scalar, or vice versa, then that would have consequences, but neither the scalar nor the local remembers where its contents came from or inherits or acquires a link to the other beast.

            If this remains puzzling, please show specific code and show its specific results.


            Comment


            • #7
              Hi Nick!

              First, I'd like to thank you for the clarity and grace you brought to answering this question! Your answer was so good that it worked for my purposes, too. I write with a quick follow-up question, if you would be willing and able to answer. Here's what I've done:
              Code:
                  xtset countryid /* nested var */
                  xtsum gdp if missing == 0
                  local n : di r(n)
                  local N : di r(N)
              
                  graph ... ///
                  , note("Note Analytic sample sizes N = `N', n = `n'")
              This code ran flawlessly (thanks to the discussion above). My question is: why are di r(n) and di r(N) considered extended macro functions and thus require the colon, :? Why won't a simple blank or an equals sign work, too? Does the "extended" essentially mean that what comes after the macro name is neither string, numeric, nor expression, but rather a command and, therefore, must be denoted differently? I looked in the user manual (U 18.3.6) but this question is not explicitly answered there (i.e. extended vs. normal macro functions are not differentially defined).

              Best,
              Daniel

              Comment


              • #8
                It's good question but I don't have a profound answer. I imagine that at root it's a little arbitrary what's called extended, but a common pattern is an implied two-step, namely first evaluate this expression, and then put the result in a macro.

                Comment

                Working...
                X