Announcement

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

  • Combining mlabel margins and mlabel p values in one coefplot

    Dear Statalists,

    My question is about combining 2 types of mlabels in one coefplot in Stata 15.

    I created a coefplot that displays margins of a logistic regression with the following command:

    . coefplot, xline(0) mlabel format(%9.2g) mlabposition(12) mlabgap(*2)

    I would like to add the pvalues in the same coefplot in the following manner:

    . coefplot, xline(0) mlabposition(2) mlabel(cond(@pval<.001, "***", cond(@pval<.01, "**", cond(@pval<.05, "*", "")))) note("* p < .05, ** p <.01, *** p <.001")

    When I put both mlabel and mlabel(cond(@pval<.001, "***", cond(@pval<.01, "**", cond(@pval<.05, "*", "")))) note("* p < .05, ** p <.01, *** p <.001") in the same command, the p values are not displayed.

    How can I combine the two mlabels in one coefplot?

    Thanks a lot in advance!

    Regards, Anouk

  • #2
    coefplot is from Stata Journal. Please note the advice to identify community contributed commands and to present reproducible examples (FAQ Advice #12). The default specifying the option -mlabel- is to show the coefficient values next to their respective markers. Otherwise, -mlabel- option as in twoway scatter accepts a variable as input, which provides scope for you to program what you want. The following code is adapted for Stata 15, but a more efficient way to extract matrices is available in Stata 16 and later versions.

    Code:
    version 15
    webuse lbw, clear
    probit low age lwt smoke i.race
    preserve
    mat rtable= r(table)
    mat res= (r(table)["b", 1...]\r(table)["pvalue", 1...])'
    svmat res
    drop if res1==0
    format res1 %9.3f
    gen label= cond(res2<0.001, string(res1)+"***", ///
    cond(inrange(res2, 0.001, 0.0499), string(res1)+"**", ///
    cond(inrange(res2, 0.005, 0.0999), string(res1)+"*", string(res1))))
    coefplot, xline(0) mlabposition(2) mlabel(label) scheme(s1color)
    restore
    Click image for larger version

Name:	Graph.png
Views:	1
Size:	35.3 KB
ID:	1563969

    Comment


    • #3
      Dear Andrew,

      Thanks for your help. I just found out that my version of Stata is 15.1
      When I run your code: mat res= (r(table)["b", 1...]\r(table)["pvalue", 1...])' an error invalid syntax r(198) appears.

      Is there another way to achieve your coefplot with coefficients & pvalues for stata 15.1?

      Thank you!

      Comment


      • #4
        Sorry for the confusion. I created matrix rtable to avoid using r(table), so change that line to

        Code:
        mat rtable= r(table)
        mat res= (rtable["b", 1...]\rtable["pvalue", 1...])'
        EDIT: I am not even sure that the above syntax will work in Stata 15, and version control clearly does not work from #2, so you could also try

        Code:
        mat rtable= r(table)
        mat res= (rtable[rownumb(rtable, "b"), 1...]\rtable[rownumb(rtable, "pvalue"), 1...])'
        Last edited by Andrew Musau; 17 Jul 2020, 17:09.

        Comment


        • #5
          Thanks a lot, the first code works already!!

          How could I add in the code to wrap up the coefficients to three decimals ?

          Comment


          • #6
            For strings, you can specify the display format as below

            Code:
            gen label= cond(res2<0.001, string(res1,"%9.3f")+"***", ///
            cond(inrange(res2, 0.001, 0.0499), string(res1,"%9.3f")+"**", ///
            cond(inrange(res2, 0.005, 0.0999), string(res1,"%9.3f")+"*", string(res1,"%9.3f"))))
            coefplot, xline(0) mlabposition(2) mlabel(label) scheme(s1color)

            Comment


            • #7
              Thanks a lot Andrew, my coefplot is now exactly the way I wanted it to be!

              Comment


              • #8
                Is it also possible to combine multiple coefplots with corresponding mlabels in one figure?

                I've generated labels for every coefplot seperately.

                Thanks in advance!

                Comment


                • #9
                  Yes. The only requirement is that observations of the variable holding the labels should be ordered following coefficients in the combined coefplot. See Ben's method here to combine multiple models or using a matrix here.
                  Last edited by Andrew Musau; 22 Jul 2020, 16:31.

                  Comment


                  • #10
                    Thanks for your reply. In Ben's method there are two coefficients in the same graph. I tried your code as well for the matrix, but there was an error of invalid syntax in:
                    mat R= nullmat(R)\((r(table)["b", "weight"])\ (r(table)["ll".."ul", "weight"]))'

                    I think I mean a slightly different combination of coefplots, here is an example attached.Coefplots.gph

                    I tried to combine some codes and ended up with this figure, although some coefficients & p-values are missing. How can I get a combination of coefplots like this with all coefficients & p-values displayed?

                    Thanks in advance!
                    Attached Files

                    Comment


                    • #11
                      When I add another subgraph in the coefplot, even more coefficients (mlabels) are missing. It seems like the total number of displayed mlabels corresponds with the number of independent variables...

                      Comment


                      • #12
                        I explain the principle here. If you struggle, provide a data example.

                        Comment


                        • #13
                          I'm still struggling, so here is a data example.

                          webuse lbw, clear

                          * creating label for logistic regression on: 'low' odds ratios & p values

                          logistic low age lwt race

                          estimates store low

                          mat rtable= r(table)

                          mat res = (rtable["b", 1...]\rtable["pvalue", 1...])'

                          svmat res

                          drop if res1 == 0

                          format res1 %9.3f

                          gen label_low= cond(res2<0.001, string(res1,"%9.3f")+"***", cond(inrange(res2, 0.001, 0.0099), string(res1,"%9.3f")+"**", cond(inrange(res2, 0.01, 0.0499), string(res1,"%9.3f")+"*", string(res1,"%9.3f"))))

                          * creating label for logistic regression on: 'ui' odds ratios & p values

                          logistic ui age lwt race

                          mat rtable= r(table)

                          mat res_ui = (rtable["b", 1...]\rtable["pvalue", 1...])'

                          svmat res_ui

                          drop if res_ui1 == 0

                          format res_ui1 %9.3f

                          gen label_ui = cond(res2<0.001, string(res_ui1,"%9.3f")+"***", cond(inrange(res_ui2, 0.001, 0.0099), string(res_ui1,"%9.3f")+"**", cond(inrange(res_ui2, 0.01, 0.0499), string(res_ui1,"%9.3f")+"*", string(res_ui1,"%9.3f"))))

                          * store results for coefplot

                          logistic low age lwt race

                          estimates store low

                          logistic ui age lwt race

                          estimates store ui

                          coefplot low, mlabel(label_low) || ui, mlabel(label_ui)

                          I'm struggling with two things:

                          1. My coefplot looks like this (attachment), with missing mlabels for the odds ratios of race & _cons. Also, the mlabels in ui, are the ones that belong to low. When I plot the coefplots seperately for low & ui, all mlabels are present. Something is going wrong when I plot multiple graphs...

                          How can I put the corrects mlabels to the corresponding subgraphs?


                          2. For example in ui, odds ratio for weight at last menstrual period = 2.767, although in the coefplot it looks on the x-axis like it is -0.2... How can I put the odds ratios in the right position in the graph?


                          Thanks in advance!
                          Attached Files
                          Last edited by Anouk Klootwijk; 23 Jul 2020, 12:33.

                          Comment


                          • #14
                            In the future, please upload graph attachments in .png format.You can append this to the code in #13

                            Code:
                            preserve
                            keep label_low label_ui order
                            drop if label_low=="." & label_ui=="."
                            expand 2, gen(n)
                            replace label_low= label_ui if n
                            sort order n
                            coefplot low, mlabel(label_low) || ui, mlabel(label_low)
                            restore
                            All I did was to order the labels 11223344 corresponding to 1st coefficient left graph, 1st coefficient right graph, 2nd coefficient left graph, 2nd coefficient right graph, and so on.


                            ADDED IN EDIT: Had not noticed #2 in your post in #13. It seems to me that one unit in the axis scale represents 2 units in the coefplot graph. The equation is: New \(x\) = 2*Old \(x\) + 1. Therefore, you can change the labels as follows:

                            Code:
                            coefplot low, mlabel(label_low) || ui, mlabel(label_low) xlab(-2 "-3"  0 "1"  2 "5"  4 "9")
                            Res.:
                            Click image for larger version

Name:	Graph.png
Views:	1
Size:	47.7 KB
ID:	1565041

                            Last edited by Andrew Musau; 23 Jul 2020, 17:09.

                            Comment


                            • #15
                              Hi Andrew,

                              Thanks a lot for your explanation, this works!! I removed the command order, because the error 'variable order not found r(111)' appeared.

                              How should I transform the code for a third coefplot?

                              For example

                              webuse lbw, clear

                              * create third label for ht
                              . logistic ht age lwt race
                              mat rtable=r(table)
                              mat res_ht = (rtable["b", 1...]\rtable["pvalue", 1...])'
                              svmat res_ht
                              drop if res_ht1 == 0
                              format res_ht1 %9.3f
                              gen label_ht = cond(res2<0.001, string(res_ht1,"%9.3f")+"***", cond(inrange(res_ht2, 0.001, 0.0099), string(res_ht1,"%9.3f")+"**", cond(inrange(res_ht2, 0.01, 0.0499), string(res_ht1,"%9.3f")+"*",string(res_ht1,"%9.3f" ))))

                              * store results ht
                              logistic ht age lwt race
                              estimate store ht

                              I tried the following:

                              keep label_low label_ui label_ht
                              drop if label_low=="." & label_ui=="." & label_ht=="."
                              expand 3, gen(n)

                              The n consists of 0 & 1, I think I need 0, 1 and 2 to be able to replace the labels for three graphs...
                              What command can I use ?

                              Thanks in advance!
                              Last edited by Anouk Klootwijk; 24 Jul 2020, 04:12.

                              Comment

                              Working...
                              X