Announcement

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

  • How to write loops that fill a matrix successively

    Hello,

    I've got a question regarding the writing of loops: What I would like to do is to write a loop that picks every variable I've got (except for one) consecutively, then calculates the correlation of the variable that is not included with each of the other included variables and writes the correlation coefficient into an empty matrix, that I have created beforehand.
    My problem is the following:
    If I write:
    foreach k in `varlist' {
    forvalues i = 1/10 {
    forvalues j = 1/100 {
    quietly corr g_russia `k'
    matrix corr_with_russia [`i',`j']=r(rho)
    }
    }
    }

    Then Stata picks the first entry of my variable list, e.g. g_usa, and fills the whole matrix with the values of the correlation of Russia and the USA. But what I would rather like to do is to compute this correlation and put it in the first row and first column-entry of the matrix. The correlation coefficient for e.g. Spain should then be listed in the second column, first row.
    But I don't know how to tell Stata to pick the first variable out of a variable list of 100 variables and only change the first entry of the matrix with the values of this variable;
    then it should pick the second variable, compute a correlation coefficient and insert this as the second entry and so....

    Wouldn't I have to assign numbers to the variables in the varlist to achieve this?

    Hope it's halfway clear what I'm struggling with.

    Thank's for the support.

  • #2
    What you want is a vector, so in Stata a matrix with one row or with one column. A more general version of the code is already implemented in cpcorr (SSC).


    Code:
    . sysuse auto, clear
    (1978 Automobile Data)
    
    . cpcorr headroom-displacement \ mpg
    (obs=74)
    
                      mpg
        headroom  -0.4138
           trunk  -0.5816
          weight  -0.8072
          length  -0.7958
            turn  -0.7192
    displacement  -0.7056
    
    . ret li
    
    scalars:
                      r(N) =  74
    
    matrices:
                      r(C) :  6 x 1
                      r(p) :  6 x 1
    
    . mat table = r(C)
    
    . mat li table
    
    table[6,1]
                         mpg
        headroom  -.41380299
           trunk  -.58158503
          weight  -.80717486
          length  -.79577944
            turn  -.71918633
    displacement  -.70564259
    .
    Depending on the contents of your local varlist this code is closer to what you seek:



    Code:
    local I : word count `varlist'
    matrix wanted = J(`I', 1, .)
    
    local i = 1
    foreach k in `varlist' {
        quietly corr g_russia `k'
        matrix wanted [`i', 1] = r(rho)
        local ++i
    }

    The key -- and it's hard to get right as a learner -- is that you have only one loop to perform, but you need within each iteration to choose a new variable AND a new row (or equivalently column) of the matrix. So, you can write the loop as a loop over variables, and at the same time bump up the row counter. It can be done the other way round too.


    Code:
    local I : word count `varlist'
    tokenize `varlist'
    matrix wanted = J(`I', 1, .)
    
    forval i = 1/`I'  {
        quietly corr g_russia ``i''
        matrix wanted [`i', 1] = r(rho)
    }
    There are other ways too.
    Last edited by Nick Cox; 04 Oct 2020, 07:36.

    Comment


    • #3
      It is not clear. If you have k variables, there are k correlations with the omitted variable. So it is not clear with what you want to fill up a 10 by 100 matrix.

      Otherwise for when you re looping through variables, you dont need to number them, but you can increment another macro, like this

      Code:
      
      . sysuse auto, clear
      (1978 Automobile Data)
      
      . mat Holder = J(1,7,.)
      
      . local j = 1
      
      . foreach var of varlist price-length {
        2. corr `var' turn
        3. mat Holder[1,`j']= r(rho)
        4. local ++j
        5. }
      (obs=74)
      
                   |    price     turn
      -------------+------------------
             price |   1.0000
              turn |   0.3096   1.0000
      
      (obs=74)
      
                   |      mpg     turn
      -------------+------------------
               mpg |   1.0000
              turn |  -0.7192   1.0000
      
      (obs=69)
      
                   |    rep78     turn
      -------------+------------------
             rep78 |   1.0000
              turn |  -0.4961   1.0000
      
      (obs=74)
      
                   | headroom     turn
      -------------+------------------
          headroom |   1.0000
              turn |   0.4245   1.0000
      
      (obs=74)
      
                   |    trunk     turn
      -------------+------------------
             trunk |   1.0000
              turn |   0.6011   1.0000
      
      (obs=74)
      
                   |   weight     turn
      -------------+------------------
            weight |   1.0000
              turn |   0.8574   1.0000
      
      (obs=74)
      
                   |   length     turn
      -------------+------------------
            length |   1.0000
              turn |   0.8643   1.0000
      
      
      . matlist Holder
      
                   |        c1         c2         c3         c4         c5         c6         c7 
      -------------+-----------------------------------------------------------------------------
                r1 |  .3096174  -.7191863  -.4961308   .4244646   .6010595   .8574429   .8642612 
      
      .

      Comment


      • #4
        Indeed I really needed a matrix, not just a row or column vector; but I thought it would be unnecessary difficult to explain.
        What helped the most was the
        "local ++i" command. So many thanks for your help.

        Comment


        • #5
          What should help too is the signal that cpcorr (SSC) can indeed generate a matrix of correlations with I >= 1 rows and J >= 1 columns. The explanation in #2 was tailored to the question you asked.

          Comment

          Working...
          X