Announcement

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

  • psmatch2 & loop - Results not showing

    Hi all,

    I want to match bonds with the same company and credit rating. Therefore, I use a loop to perform psmatch2 in each group. However, I noticed that when running psmatch2 within the loop, the colomns of matching results, such as _id, _n1, and _weight, are not displayed. How should I modify the code to show these results?
    Additionally, I would like to obtain the differences in independent variables(IndVar in my code) for the matched pairs. How should I proceed with this?


    Code:
    egen firmrating = group(RefinitivTicker SumRatingScale)
    g att= .
    levels firmrating, local(gr)
    foreach j of local gr {
        capture psmatch2 Dummy V1 V2 V3 V4 V5 if firmrating == `j', out(IndVar)
        
        * Check if there was an error (no observations)
        if _rc != 0 {
            di "Warning: No observations for group `j'"
        }
        else {
            * Your additional code here, if needed
            replace att = r(att) if firmrating == `j'
        }
    }

  • #2
    psmatch2 is from SSC (FAQ Advice #12).

    However, I noticed that when running psmatch2 within the loop, the [columns] of matching results, such as _id, _n1, and _weight, are not displayed.
    Do you mean that these variables are not created? If the command exits with an error message, then that would be one reason. Provide a data example for one group for which the command executes and the variables are not created.

    Code:
    dataex Dummy V1 V2 V3 V4 V5 IndVar if firmrating == XX
    where you replace "XX" with the corresponding value of firmrating.

    Comment


    • #3
      Thanks Andrew for your reply. I have 450 groups. And yes, some of them will return "no observations error". That's the reason I used "capture" in my code.
      Below is one of the examples that return error.

      Code:
       dataex Dummy V1 V2 V3 V4 V5 IndVar if firmrating == 5
      Results:

      * Example generated by -dataex-. To install: ssc install dataex
      clear
      input byte GreenBond int IssueDate double(CouponRate OriginalAmountIssued) float MaturityDate_stata double MatchedYield
      0 20297 4.75 1.500e+09 23950 4.784
      0 20562 4.8 1.000e+09 24214 4.822
      0 23182 5.5 7.500e+08 26927 5.561
      0 22971 5.125 1.000e+09 26716 5.184
      0 20297 4.75 1.500e+09 23950 4.784
      0 20562 4.8 1.000e+09 24214 4.822
      0 20552 5.6 3.000e+08 26030 5.6
      0 22627 3.324 1.000e+09 28196 3.324
      0 22831 5.5 7.500e+08 26576 5.502
      0 22627 3.324 1.000e+09 28196 3.324
      end
      format %td IssueDate
      format %td MaturityDate_stata

      Comment


      • #4
        In this case, all the bonds are non-green bonds, so the outcome does not vary. Is your objective to match green bonds and non-green bonds?

        Comment


        • #5
          Yes. My goal is to match green bonds and non-green bonds, and get the IndVar difference of the matched pairs.

          Another example from firmrating groups is as below. (Having green bonds and non-green bonds in the same group but still failed in matching)

          * Example generated by -dataex-. To install: ssc install dataex
          clear
          input byte GreenBond int IssueDate double(CouponRate OriginalAmountIssued) float MaturityDate_stata double MatchedYield
          0 21269 4.35 3.000e+08 32247 4.361
          0 20221 3.45 5.250e+08 23893 3.471
          0 20585 2.95 4.750e+08 24237 2.954
          0 21970 2.3 7.000e+08 25627 2.312
          0 20048 3.5 3.000e+08 23695 3.59
          0 20951 3.35 4.000e+08 24606 3.391
          0 20408 3.5 3.000e+08 24060 3.539
          0 21138 3.2 4.500e+08 24851 3.247
          1 22538 2.05 7.000e+08 26312 2.063
          0 20732 3.9 3.500e+08 31699 3.923
          0 22986 5 3.500e+08 26709 5.05
          1 22602 1.9 4.000e+08 25172 1.92
          0 21684 3.3 4.500e+08 25354 3.305
          0 22057 2.45 6.000e+08 25947 2.498
          0 20991 4.15 3.000e+08 31958 4.15
          0 23351 5.3 4.000e+08 27004 5.308
          0 20732 2.9 3.000e+08 24394 2.936
          end
          format %td IssueDate
          format %td MaturityDate_stata


          Thanks again!

          Comment


          • #6
            Note that the matching algorithm runs a logistic regression to compute the propensity scores. Here, you have one of the predictors "Coupon rate" predicting the data perfectly, i.e., all green bonds have Coupon rate <2.05 (and correspondingly, all non-green bonds have Coupon rate > 2.05). See https://stats.oarc.ucla.edu/other/mu...ith-the-issue/. Here, you can drop that variable to allow the logistic regression to run. Only in cases where the matching algorithm encounters no errors can you be able to complete your task. If you present one such case, I can provide example code.

            Comment


            • #7
              Are you saying that the result field will only appear if the psmatch2 for each group inside the loop is successful?
              I have already removed the Coupon Rate, but there are still some groups that cannot undergo matching. Should I remove these groups as well?

              Comment


              • #8
                Hi Andrew,
                I remove all the groups that return "no observations". Finally, STATA shows the results column! However, only matching data for the last group will be kept. How can I keep the matching data of previous groups?
                Thanks for your guidance all along!
                Click image for larger version

Name:	Untitled.png
Views:	1
Size:	61.0 KB
ID:	1740971

                Comment


                • #9
                  psmatch2 will overwrite previous results, so you need to calculate the differences before the next iteration of the loop. Or do this in separate frames.

                  Code:
                  egen firmrating = group(RefinitivTicker SumRatingScale)
                  g att= .
                  levels firmrating, local(gr)
                  foreach j of local gr{
                      frame put * if firmrating==`j', into(gr`j')
                      frame gr`j'{
                          psmatch2 Dummy V1 V2 V3 V4 V5 if firmrating == `j', out(IndVar)
                      }
                  }
                  frames dir
                  
                  *TO VIEW A SPECIFIC FRAME - E.G., 466
                  frame change gr466
                  
                  *TO REVERT TO DEFAULT FRAME
                  frame change default

                  Comment


                  • #10
                    Alternatively, to have all results in one frame, create 3 new variables and replace these variables with values of the variables generated by psmatch2.

                    Code:
                    foreach var in n1 id weight{
                        gen `var'=.
                    }
                    
                    egen firmrating = group(RefinitivTicker SumRatingScale)
                    g att= .
                    levels firmrating, local(gr)
                    foreach j of local gr{
                        psmatch2 Dummy V1 V2 V3 V4 V5 if firmrating == `j', out(IndVar)
                        foreach var in n1 id weight{
                            replace `var'=_`var' if firmrating == `j'
                        }
                    }

                    Comment


                    • #11
                      I got it. Many thanks for your help! Wish a good day

                      Comment

                      Working...
                      X