Announcement

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

  • Creating temporary variables (tempvar) with svmat

    Dear Statalist,

    I am creating a simple program to graph some results of the margins command in combination with other graphs. For this I need to transform matrixes into variables, and I rely on the svmat command to do so. However I would like svmat to generate temporary variables (tempvar) so that they are not stored in the dataset once the program has been executed. I have tried to generate temporary variables with svmat without success. Is there any way to do it or should I use a different procedure to transform matrixes into variables? Here you have the relevant part of my original code in which svmat generates 10 regular variables from matrix C:

    Code:
    matrix A = r(at) 
    matrix B = r(table)'
    local maxat = `points' + 1 
    matrix D = A[1..`maxat', "`varlist'"]
    matrix C = B, D
    svmat C, names(c)

    And here you can find the code I used to generate temporary variables without success:

    Code:
    matrix A = r(at) 
    matrix B = r(table)'
    local maxat = `points' + 1 
    matrix D = A[1..`maxat', "`varlist'"]
    matrix C = B, D
    tempvar c1 c2 c3 c4 c5 c6 c7 c8 c9 c10
    svmat C, names(`c')
    Thank you.

    Enrique

  • #2
    I suspect that there are better ways of doing what you want, especially using Mata. But to answer the question, the problem is that

    1. Your tempvar names are just names for you to talk to Stata about particular variables, which really have names like __000123 or __000042, half of the point being that the names Stata uses are utterly unpredictable in advance.

    2. svmat wants a stub and your `c' can in no way be a stub for the real names just mentioned. In the context of your code, it's an undefined local macro that evaluates to an empty string and I guess that svmat threw you out quite brutally.

    3. Stata uses the stub __ (double underscore) for temporary variables, but watch out, as in any nontrivial context there will be many other temporary variables, either that you create or that other programs create for you.

    Here's a solution that I think solves all these problems. Use a prefix ___ (triple underscore). It's my understanding that Stata never uses that for temporary variables. You just need to clean up afterwards, which will be easy.

    Code:
     
    . sysuse auto
    (1978 Automobile Data)
    
    . mkmat price mpg, mat(A)
    
    . svmat A, name(___)
    
    . ds
    make          rep78         weight        displacement  ___1
    price         headroom      length        gear_ratio    ___2
    mpg           trunk         turn          foreign
    
    . drop ___*
    Another solution is this:

    Code:
     
    tempname stub 
    svmat A, name(`stub') 
    drop `stub'*
    Note that the variables created were `stub'1 `stub'2 and so forth.

    That's probably a better solution.

    It says somewhere that you shouldn't assume that you can add suffixes to temporary variable names, but in practice you can add suffixes of modest length. Even in Stata 14, the variables and scalars associated with temporary names are just 8 characters long, so for problems like yours, adding suffixes should be fine.

    But I think it's true that you need to do your own clean up, as above.


    Comment


    • #3
      Dear Nick,

      Thanks very much for your detailed response. It really helped.

      Comment


      • #4
        Hi Enrique and Nick,

        I've just been bitten by this myself. Nick's response suggests that svmat really isn't fit for purpose anymore. A glance at the ado-file shows that it was written for Stata 4.0!!

        In case it helps anyone, below is my hacked code that uses tempvars.

        Thanks,

        David.



        Code:
        // Assume matrix `A' has already been identified/declared, e.g. using syntax
        
        capture {
            local nr = rowsof(matrix(`A'))
            local nc = colsof(matrix(`A'))
        }
        if _rc {
            disp as err "matrix {bf:`A'} not found"
            exit 111
        }
        
        // declare tempvars
        forvalues j = 1/`nc' {
            tempvar tv`j'
        }
        
        // now transfer the matrix data into the tempvars
        // (this is basically all that svmat.ado does, as far as I can tell)
        local old_N = _N
        if `nr' > _N nois set obs `nr'
        capture {
            local j = 1
            while `j' <= `nc' {
                gen `tv`j'' = matrix(`A'[_n, `j']) in 1/`nr'
                local ++j
            }
        }
        if _rc {
            qui drop if _n > `old_N'
            exit _rc
        }
        cap compress `tv1'-`tv`nc''
        
        // REST OF SCRIPT, USING TEMPVARS `tv1', `tv2' ...
        
        // at the end, you'll still need to drop any additionally-created observations, if appropriate
        qui drop if _n > `old_N'

        Comment


        • #5
          svmat is a fossil, because its key purpose is to save Stata matrices. Stata matrices still have many uses, but since Stata 9 we have Mata.

          I guess the StataCorp point of view on svmat is

          1. It's not broken because it does what was intended.

          2. There are better ways to work with matrices.

          3. There are many more important commands to write and to maintain.

          Comment


          • #6
            Nick, could I confirm your message more explicitly ... would you say svmat and mkmat are better replaced with putmata and getmata? I have also seen that st_data does similar things
            Last edited by Sean Fiedler; 08 Jun 2017, 10:46.

            Comment


            • #7
              If you wish to work with Mata you need to use the newer commands. If you want Stata matrices, the older commands remain useful.

              svmat and mkmat are fossils but fossils can still be interesting and even useful.

              Comment

              Working...
              X