Announcement

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

  • Mata condition in Stata program

    Dear all,

    I'm writing a Stata program, using pieces of Mata in it.

    I face troubles when trying to put a Mata if condition in it, I think because the closing bracket } is read as a Stata bracket and not a Mata one.
    Or if I try to write all Mata code into a mata -- end environment, the end command leads to the following error "
    unexpected end of line
    "
    Let me drawn an example :


    Using a line by line mata indicator
    Code:
    clear
    nwclear
    mata : mata clear
    
    *local mat=0 /*Pick one of the two configuration, in reality depends on the options specified in the program*/
    local mat=1
    
    if `mat'==1{
    mata A =(0,3, 10\ 2, 0, 5\ 1, 1, 0)  /*In reality the matrix considered comes from the program itself*/
    noi display "case 1 : matrix A exists, should be modified if not symmetric "
    
    mata : sym=issymmetric(A)
    mata : sym
    mata : if (sym==0) {
    mata : Z = A :* (A :< A') + A' :* (A' :< A) /*min of symmetrics elements : reciprocated ties*/
    }
    }
    
    if `mat'!=1{
    noi di "case 2 : matrix A does not exit"
    }



    Using a mata - end environment.
    Code:
    clear
    nwclear
    mata : mata clear
    
    *local mat=0 /*Pick one of the two configuration, in reality depends on the options specified in the program*/
    local mat=1
    
    if `mat'==1{
    mata A =(0,3, 10\ 2, 0, 5\ 1, 1, 0)  /*In reality the matrix considered comes from the program itself*/
    noi display "case 1 : matrix A exists, should be modified if not symmetric "
    
    mata :
    sym=issymmetric(A)
    sym
    if (sym==0) {
     Z = A :* (A :< A') + A' :* (A' :< A) /*min of symmetrics elements : reciprocated ties*/
    }
     end
    }
    
    if `mat'!=1{
    noi di "case 2 : matrix A does not exit"
    }

  • #2
    Hi
    I haven't read your code in detail, but what works for me is keeping Stata and Mata apart except for some Mata function calls from Stata.
    So I build a set of Mata tools/functions/classes that has a very simple functionality.
    And I test these before carrying on.
    Then I build a Stata structure that rely on my Mata tools.
    Sometimes I have to redefine my Mata code in order to get it to work.

    My advices in short are:
    1. Keep Stata and Mata apart as much as possible
    2. Use function calls to get things done in Mata from Stata
    3. Make Mata functions simple and for one purpose only (that actually applies to Stata code as well)
    4. Make most of your code in Mata (Here someone probably will disagree)
    Hope this helps - It does for me
    Kind regards

    nhb

    Comment


    • #3
      Come to think of it I have an small example that might show what I mean.
      I have my own command for summarizing missings:

      Code:
      program define nonmissings, rclass
          syntax [varlist] [if] [in] [, Missings]
          tempvar touse
          mark `touse' `if' `in'
      
          mata: st_matrix("__tabmiss", nonmissings("`varlist'", "`touse'", "`missings'" == "missings"))
          
          matrix coleq __tabmiss = Counts Counts Frequency
          if "`missings'" == "missings" {
              matrix colnames __tabmiss = NonMissings Missings Missings
          }
          else {
              matrix colnames __tabmiss = NonMissings Missings NonMissings
          }
          matrix rownames __tabmiss = `varlist'
          //scalar N = `r(N)'  //__tabmiss[1,1] + __tabmiss[1,2]
          local __rspec = "--" + (rowsof(__tabmiss) - 1) * "&" + "-"
          quietly count if `touse'
          matlist __tabmiss, title(Missing observations, N = `=r(N)') rowtitle(Variable) ///
                          cspec(| %-32s | %12.0f & %12.0f | %12.2f |) ///
                          rspec(`__rspec')
          return matrix result = __tabmiss
          local drop __rspec
      end
      
      
      mata:
          function nonmissings(varlist, touse, missings)
          {
              vl = tokens(varlist)
              out = J(0, 3, .)
              for(vn=1; vn<=cols(vl); vn++) {
                  if ( st_isnumvar(vl[vn]) ) {
                      test = st_data(., vl[vn], touse)
                      nonmiss = colsum(J(rows(test), 1, .) :> test)
                  } else if ( st_isstrvar(vl[vn]) ) {
                      test = strtrim(st_sdata(., vl[vn], touse))
                      nonmiss = colsum(J(rows(test), 1, "") :< test)
                  } else {
                      nonmiss = .
                  }
                  N = rows(test)
                  if ( missings ) {
                      out = out \ (nonmiss, N - nonmiss, (N - nonmiss) / N * 100)
                  } else {
                      out = out \ (nonmiss, N - nonmiss, nonmiss / N * 100)
                  }
              }
              return (out)
          }
      end
      Also I've become quite fond of sending output into a matrix in Stata and using -matlist- to present the results
      Kind regards

      nhb

      Comment


      • #4
        Ok, thank you Niels for your answer, and the example.

        If I get you right, I should built a Mata function that returns a Stata scalar if my matrix is symmetric, and use this Stata scalar to do a simple condition in my Stata program.

        Thanks again,
        best,
        Charlie

        Comment


        • #5
          Exactly, except that you'll probably has to build some Mata code that sets a Stata scalar when called instead.
          Good luck
          Kind regards

          nhb

          Comment


          • #6
            It does work!

            Thanks a lot,
            Charlie

            Comment

            Working...
            X