Announcement

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

  • How to drop specific columns and rows in matrix?

    I created a matrix named "m" with the following commands.

    Is there a simple way to remove all the rows and columns starting with "/:" or ending with ":_cons"?

    Code:
    webuse auto.dta, clear
    gen int1 = headroom * mpg
    sem(weight <- headroom mpg int1)(price <- weight headroom mpg int1)
    mat m = e(V)
    mat list m
    
    ---
    
    symmetric m[11,11]
                            weight:        weight:        weight:        weight:         price:         price:         price:         price:         price:             /:             /:
                          headroom            mpg           int1          _cons         weight       headroom            mpg           int1          _cons  var(e.weight)   var(e.price)
    weight:headroom      102070.61
         weight:mpg      13858.559      1981.9523
        weight:int1     -4794.1639     -666.58196      234.94889
       weight:_cons      -304632.4      -42530.83      14038.399      953243.42
       price:weight      3.743e-12      4.958e-13     -1.746e-13     -1.099e-11      .42736644
     price:headroom     -2.781e-08     -3.508e-09      1.189e-09      8.446e-08      -307.2345      3448866.5
          price:mpg     -3.368e-09     -4.182e-10      1.419e-10      1.022e-08       9.181739      431677.77      62876.738
         price:int1      1.300e-09      1.635e-10     -5.738e-11     -3.826e-09      11.587202     -159946.05     -20831.787      7744.4502
        price:_cons      6.341e-08      7.809e-09     -2.510e-09     -2.009e-07      -1281.844     -8712515.3     -1372582.2      409211.32       33991200
    /:var(e.weight)      5.831e-08      8.129e-09     -1.916e-09     -2.316e-07     -2.021e-11      1.376e-08     -3.658e-10     -5.317e-10      6.045e-08      9.132e+08
     /:var(e.price)      6.178e-08      5.466e-09     -4.305e-09     -3.546e-08     -3.278e-10      7.628e-06      9.238e-07     -4.163e-07     -.00001609     -1.347e-06      9.133e+11

  • #2
    You need to search through equation names and column/row names, but it helps that your matrix is symmetric (so either rows or columns). The following uses matselrc from Stata Journal, authored by Nick Cox.

    Code:
    webuse auto.dta, clear
    gen int1 = headroom * mpg
    sem(weight <- headroom mpg int1)(price <- weight headroom mpg int1)
    mat m = e(V)
    mat list m
    
    local coleq: coleq m
    local coln: coln m
    
    local i 0
    local list1 ""
    foreach eq of local coleq{
       local ++i
       if "`eq'"=="/"{
          local list1 "`list1' `i'"
       }
    }
    
    local i 0
    local list2 ""
    foreach nm of local coln{
       local ++i
       if "`nm'"=="_cons"{
          local list2 "`list2' `i'"
       }
    }
    
    local i 0
    local all ""
    foreach nm of local coln{
       local ++i
       local all "`all' `i'"
    }
    
    local list: list all-list1
    local list: list list-list2
    *findit matselrc and click link to install 
    matselrc m m2, r(`list') c(`list')
    mat l m2
    Converting to a dataset, dropping the unwanted rows and columns and back to a matrix is another solution. See

    Code:
    help svmat
    Res.:

    Code:
    . mat l m2
    
    symmetric m2[7,7]
                         weight:     weight:     weight:      price:      price:      price:      price:
                       headroom         mpg        int1      weight    headroom         mpg        int1
    weight:headroom   102070.61
         weight:mpg   13858.559   1981.9523
        weight:int1  -4794.1639  -666.58196   234.94889
       price:weight   3.743e-12   4.958e-13  -1.746e-13   .42736644
     price:headroom  -2.781e-08  -3.508e-09   1.189e-09   -307.2345   3448866.5
          price:mpg  -3.368e-09  -4.182e-10   1.419e-10    9.181739   431677.77   62876.738
         price:int1   1.300e-09   1.635e-10  -5.738e-11   11.587202  -159946.05  -20831.787   7744.4502

    Comment


    • #3
      Andrew Musau's helpful reply mentioned matselrc which is from this article in 2000:

      ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
      package dm79 from http://www.stata.com/stb/stb56
      ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

      TITLE
      STB-56 dm79. Yet more matrix commands

      DESCRIPTION/AUTHOR(S)
      STB insert by Nicholas J. Cox, University of Durham, UK
      Support: [email protected]
      After intallation see help matcorr, help matselrc, help matvech,
      help matvtom, help svmatsv, help matewmf, help matvec,
      help matvsort, and help svmat2

      Comment


      • #4
        Originally posted by Andrew Musau View Post
        You need to search through equation names and column/row names, but it helps that your matrix is symmetric (so either rows or columns). The following uses matselrc from Stata Journal, authored by Nick Cox.

        Code:
        webuse auto.dta, clear
        gen int1 = headroom * mpg
        sem(weight <- headroom mpg int1)(price <- weight headroom mpg int1)
        mat m = e(V)
        mat list m
        
        local coleq: coleq m
        local coln: coln m
        
        local i 0
        local list1 ""
        foreach eq of local coleq{
        local ++i
        if "`eq'"=="/"{
        local list1 "`list1' `i'"
        }
        }
        
        local i 0
        local list2 ""
        foreach nm of local coln{
        local ++i
        if "`nm'"=="_cons"{
        local list2 "`list2' `i'"
        }
        }
        
        local i 0
        local all ""
        foreach nm of local coln{
        local ++i
        local all "`all' `i'"
        }
        
        local list: list all-list1
        local list: list list-list2
        *findit matselrc and click link to install
        matselrc m m2, r(`list') c(`list')
        mat l m2
        Converting to a dataset, dropping the unwanted rows and columns and back to a matrix is another solution. See

        Code:
        help svmat
        Res.:

        Code:
        . mat l m2
        
        symmetric m2[7,7]
        weight: weight: weight: price: price: price: price:
        headroom mpg int1 weight headroom mpg int1
        weight:headroom 102070.61
        weight:mpg 13858.559 1981.9523
        weight:int1 -4794.1639 -666.58196 234.94889
        price:weight 3.743e-12 4.958e-13 -1.746e-13 .42736644
        price:headroom -2.781e-08 -3.508e-09 1.189e-09 -307.2345 3448866.5
        price:mpg -3.368e-09 -4.182e-10 1.419e-10 9.181739 431677.77 62876.738
        price:int1 1.300e-09 1.635e-10 -5.738e-11 11.587202 -159946.05 -20831.787 7744.4502
        Thanks Andrew. Your solution solved my problem.

        I am now looking for an easier solution. I remember in one version of stata (should be around version 10), we can use something like the following command to select the columns and rows

        Code:
        mat m = e(V)[(1,2,3,5,6,7,8), (1,2,3,5,6,7,8)]
        But in stata SE 16, this command seems to be no longer available as I got an error message "type mismatch" after this command. Do you know an easier way to select out specific rows and columns?

        Comment


        • #5
          Oh, I can use the following command to select out the rows and columns I need.

          Code:
          mat m = e(V)
          matselrc m m2, row(1,2,3,5,6,7,8) col(1,2,3,5,6,7,8)
          mat list m2

          Comment


          • #6
            Code:
            mata : 
            
                tokeep = selectindex(
                            
                            ustrregexm(
                            
                                st_matrixrowstripe("e(V)")[.,2],
                                
                                "_cons|^var\(.+\)$" 
                            
                            ) :== 0    
                        ) 
            
                st_matrix("m3", st_matrix("e(V)")[tokeep, tokeep'])
            
                st_matrixrowstripe("m3", st_matrixrowstripe("e(V)")[tokeep,.])
                st_matrixcolstripe("m3", st_matrixrowstripe("m3"))
                
            end

            Comment

            Working...
            X