Announcement

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

  • How to retrieve/extract scalars from a matrix based on their ROW NAMEs and COLUMN NAMEs?

    I wonder if there is a way to extract some scalars from a matrix based on their ROW NAMEs and COLUMN NAMEs?

    For example, after the -sem- command, I got an r(table) and save it to a matrix named "test".

    Code:
    use https://stats.idre.ucla.edu/stat/data/hsb2, clear
    
    rename science y  /* dependent variable   */
    rename math x     /* independent variable */
    rename read m     /* mediator variable    */
    rename write w    /* moderator variable 1 */
    rename socst z    /* moderator variable 2 */
    generate mx=m*x  /*  mv by iv interaction */
    
    sem (m <- x)(y <- m x mx)
    
    matrix test = r(table)
    The matrix "test" goes like this:
    Code:
    mat list test
    
    test[9,8]
                     m:          m:          y:          y:          y:          y:          /:
                     x       _cons           m           x          mx       _cons    var(e.m)
         b   .72480697   14.072537   .97661637     1.03094  -.01158689  -20.839211   58.719247
        se   .05798238   3.1002009   .28750807   .29697067   .00530912   15.169517   5.8719247
         z   12.500469   4.5392338   3.3968311   3.4715212   -2.182452  -1.3737558          .b
    pvalue   7.421e-36   5.646e-06   .00068171   .00051752   .02907619   .16951751          .b
        ll   .61116359   7.9962547   .41311091   .44888815  -.02199257  -50.570918   48.268113
        ul   .83845035   20.148819   1.5401218   1.6129918  -.00118122   8.8924952   71.433286
        df           .           .           .           .           .           .           .
      crit    1.959964    1.959964    1.959964    1.959964    1.959964    1.959964    1.959964
     eform           0           0           0           0           0           0           0
    
                     /:
              var(e.y)
         b   49.709937
        se   4.9709937
         z          .b
    pvalue          .b
        ll   40.862323
        ul   60.473257
        df           .
      crit    1.959964
     eform           0
    Now, I want to extract the vector in red whose column is "y:mx" and row is "ul". I know there is a way to do so:
    Code:
    scalar ymxul = test[6,5]
    display ymxul
    But, the number [6,5] is meaningless to me. Could I extract the vector based on a more meaningful way, for example, the row and column names of the vector. If yes, how to do it? Can anyone help me?

    Btw, the following command does NOT work:
    Code:
    scalar ymxul = test["ul","y:mx"]

  • #2
    Hi Victor,

    you need to let Stata determine the desired column/row number by using the matrix functions -colnumb()- and -rownumb()-:
    Code:
    use https://stats.idre.ucla.edu/stat/data/hsb2, clear
    
    rename science y  /* dependent variable   */
    rename math x     /* independent variable */
    rename read m     /* mediator variable    */
    rename write w    /* moderator variable 1 */
    rename socst z    /* moderator variable 2 */
    generate mx=m*x  /*  mv by iv interaction */
    sem (m <- x)(y <- m x mx)
    matrix test = r(table)
    scalar ymxul=test[rownumb(test,"ul"),colnumb(test,"y:mx")]
    display ymxul
    See help matrix_functions, especially help colnumb() and help rownumb().

    Or did I misread the question?

    Regards
    Bela

    Comment


    • #3
      Bela, awesome! problem solved, thanks!

      Comment


      • #4
        Hi both,

        Daniel Bela's solution is one possible but not the shortest. One can retrieve directly an element with names, like that with reg's variance-covariance matrix.

        Code:
        sysuse auto, clear
        reg price mpg weight
        di e(V)["mpg", "weight"]

        Comment


        • #5
          Hi, Emil Tenezakis and Victor Smith ,

          Emil's more parsimonious solution only works beginning in Stata 16. In Stata 15 or prior it produces the following error:

          Code:
          . version
          version 15.1
          
          . sysuse auto, clear
          (1978 Automobile Data)
           
          . reg price mpg weight
          
          <output omitted>
          .
          . di e(V)["mpg", "weight"]
          invalid syntax
          r(198);
          So for users with earlier versions of Stata, Daniel Bela 's solution is the work-around.

          Back before Stata 16, I was frustrated with Stata's inability to accept e(b) or e(V) in subsequent matrix expressions or to allow extraction of matrix elements by row or column names. So I wrote the programs mlu and mluwild. In versions of Stata 11.1 or greater, mlu behaves as I believe Victor would expect. After Stata has executed the above code, mlu gives:

          Code:
          . mlu e(V)["mpg", "weight"], verbose
          Element (1,2) of Stata matrix e(V)[3,3] = 44.601659
          Returning to Victor's example, and continuing to use Stata 15, mlu gives:
          Code:
          . version
          version 15.1
          .
          . use https://stats.idre.ucla.edu/stat/data/hsb2, clear
          (highschool and beyond (200 cases))
          .
          . rename science y
          . rename math x  
          . rename read m  
          . generate mx=m*x
          .
          . sem (m <- x)(y <- m x mx)
          
          <snip>
          .
          . matrix test = r(table)
          .
          . mat list test
          
          test[9,8]
          
          <snip>.
          
          . scalar ymxul = test[6,5]
          
          . display ymxul
          -.00118122
          .
          . *    Without the capture, the following attempt to extract an element by its row and column names throws error r(509);
          . cap noi scalar ymxul = test["ul","y:mx"]
          matrix operators that return matrices not allowed in this context
          .
          . *    But mlu succeeds in extracting the element by its row and column names:
          . mlu test["ul","y:mx"],scalar(ymxul_mlu) verbose replace
          Element (6,5) of Stata matrix test[9,8] = -.00118122
          
          .
          . display ymxul_mlu
          -.00118122
          For those working in Stata 16 or greater, some of mlu's functionality is easily duplicated by Stata commands as Emil demonstrated. However, I am unaware of another program that duplicates the behavior of mluwild, which allows users to extract a submatrix using wild cards to select multiple row or column names. For example, and again using Stata 15, one could extract from Victor's matrix named -test- a submatrix consisting only of the columns with names containing the letter "x" as follows:

          Code:
          . mluwild test[b,*x], verbose
          
                       | m         | y                    
                       |         x |         x         mx
          -------------+-----------+----------------------
                     b |   .724807 |   1.03094  -.0115869
          
          . return list
          
          macros:
                    r(nkeptrows) : "1"
                     r(keptrows) : "b"
                    r(nkeptcols) : "3"
                     r(keptcols) : "m:x y:x y:mx"
                         r(cnms) : "m:x m:_cons y:m y:x y:mx y:_cons /var(e.m) /var(e.y)"
                         r(rnms) : "b se z pvalue ll ul df crit eform"
          
          matrices:
                       r(submat) :  1 x 3
          Both mlu and mluwild accept either Stata or Mata matrices. The programs can be installed from inside Stata with the commands:

          Code:
          . view net describe mlu, from(http://digital.cgdev.org/doc/stata/MO/Misc)
          . view net describe mluwild, from(http://digital.cgdev.org/doc/stata/MO/Misc)
          Then click on (click here to install).
          Last edited by Mead Over; 02 Aug 2021, 15:37.

          Comment

          Working...
          X