Announcement

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

  • Write vector to variable, svmat with if condition

    Dear stata-users,

    I would like to write a stata matrix (actually a column vector) into a variable. Its number of rows (k) is smaller then number of observations (n) in the data. I also have a sample mark `touse'.

    Since svmat does not allow "if `touse'", when I use svmat, stata writes from the first observation and leaves n-k missing at the end.

    I have written a small C code (vectovar.c):

    #include "stplugin.h"


    STDLL stata_call(int argc, char *argv[])
    {
    int i, j, n, m, nn;

    n = SF_row(argv[0]);
    m = SF_col(argv[0]);

    // allocate memory depending on whether row- or colvector
    if(n==1){
    nn = m;
    } else {
    nn = n;
    }
    double * tmp = (double *) malloc(nn * sizeof(double));

    if(n==1){
    for(i=0; i<m; i++){
    SF_mat_el(argv[0], 1, i+1, &tmp[i]);
    }
    } else {
    for(i=0; i<n; i++){
    SF_mat_el(argv[0], i+1, 1, &tmp[i]);
    }
    }

    // store the result in stata variable
    i = 0;
    for(j=1; j <= SF_nobs(); j++){
    if(SF_ifobs(j)){
    SF_vstore(1, j, tmp[i]);
    i++;
    }
    }
    return 0;
    }

    and when I call it using

    plugin call vectovar `myvarname' if `touse', `mymatrixname'

    it does what I need.

    I think that using C for this simple task is an overkill. Is there a stata/mata solution.

    Thanks,
    Oleg

  • #2
    You can use st_matrix() and st_store() mata functions to achieve what you are doing in your C-plugin.I am not sure though how the marksample touse fit into your program. Does each row of the vector correspond to a specific observation in your dataset?

    Comment


    • #3
      Suppose mymatrix is

      1
      2
      3


      and `touse' is

      1
      0
      1
      1

      so myvarname in the data should be
      1
      .
      2
      3

      while svmat would produce missing for the last, not the second observation

      1
      2
      3
      .

      I think I need to use st_view to write the values directly into the variable, but I am not sure.

      Oleg

      Comment


      • #4
        I think the code below is more effective than using st_view and looping. It supposes that the number of rows of your matrix is equal to the number of ones in touse.
        Code:
        mata: b = st_matrix(st_local("mymatrixname"))
        mata: st_store(.,st_local("myvarname"),st_local("touse"),b)

        Comment


        • #5
          with st_view
          Code:
          gen `myvarname' = .
          mata:
          st_view(c=.,.,,st_local("myvarname"),st_local("touse"))
          for (i=1;i<=rows(b); i++)
          {
          c[i,1]=b[i,1]
          }

          Comment


          • #6
            Thanks Christophe, the solution

            quietly generate `myvarname' = .
            mata: temp1 = st_matrix("mymatrixname")
            mata: st_store(., st_local("myvarname"), st_local("touse"), temp1)

            seems to work OK. I did not know st_store had the third option: now I see it in help file.

            Cheers,
            Oleg

            Comment


            • #7
              I can even save one line:

              mata: st_store(., st_local("myvarname"), st_local("touse"), st_matrix("mymatrixname"))

              Comment


              • #8
                I have tested the other solution and it should give the same result. It is one nice feature of views to be able to change them directly.

                Comment


                • #9
                  As it looks, it should work, I have not tried it. I prefer the one-line solution
                  ​Thanks

                  Comment

                  Working...
                  X