Announcement

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

  • Fill only subset of a matrix with constant

    Hi everyone
    I am trying to fill a range of a matrix with a constant without using a loop. For example
    Code:
    mata
    A=J(30,1,.)
    now I want to fill the first 10 cells of A with 10, next 10 with 20, and final 10 with 30, without using a loop. Your help is greatly appreciated.

  • #2
    Hi
    One quick way is
    Code:
    mata (1::3) # J(10,1,10)
    Kind regards

    nhb

    Comment


    • #3
      Thanks for your reply. Actually, my problem is different than creating a matrix with such values. I am writing a function, that creates a scalar for a specific range of cells, therefore, I want to expedite the process by avoiding loops and fill the given range with with scalar.

      Comment


      • #4
        I think you have to give an example
        Kind regards

        nhb

        Comment


        • #5
          Show input and expected output
          Kind regards

          nhb

          Comment


          • #6
            Let us start with the following data set
            Code:
            * Example generated by -dataex-. To install: ssc install dataex
            clear
            input str5 type float(price qt g xn xn2)
            ""  .7716987 20.912085 0 .5023654 .5023654
            ""  .9921949 31.810627 0        . .5023654
            ""  .6832523  52.31378 0        . .5023654
            "" .07257772   80.5095 0        . .5023654
            ""  .8033369  24.06924 0        . .5023654
            ""  .6691629   69.2415 0        . .5023654
            ""  .9450985  4.560689 0        . .5023654
            ""  .4736953  7.640285 0        . .5023654
            ""  .7736345  4.939245 0        . .5023654
            "" .41668445  60.39468 0        . .5023654
            "" .21331644  80.82485 0        . .5023654
            ""   .851984  79.26154 0        . .5023654
            ""  .7618814  70.60552 0        . .5023654
            ""  .7675113  87.89279 0        . .5023654
            ""  .5456389  24.21585 0        . .5023654
            ""  .8585936  60.46348 0        . .5023654
            ""  .3758757   57.7033 0        . .5023654
            ""  .9504235  89.68988 0        . .5023654
            ""  .9620826  49.32456 0        . .5023654
            ""  .7883558  40.62389 0        . .5023654
            end
            The following code tries to generate weighted average of price, using qt as a weight. On a 6 million observations, the code take enough time. However, when do not use loop for filling values of the xn variable, the code is efficient. So I am trying to figure out how a given range of a matrix can be filled with a constant (in our example, the constant is the group weighted average mean)

            Code:
            cap drop xn
            cap drop xn2
            gen xn=.
            sort g
            mata
            mata clear
            st_view(price=., ., "price")
            st_view(gr=., ., "g")
            st_view(xn=., ., "xn")
            st_view(qt=., ., "qt")
            obs =panelsetup(gr,1) //grouping variable
            
            for (g=1; g<=rows(obs); g++) { // loop through each group
                
                X=price[|obs[g,1],1 \ obs[g,2],1|]
                Y=    qt[|obs[g,1],1 \ obs[g,2],1|]
                xn[obs[g,1],1]=sum(X :* Y) / sum(Y)
                }
            
            end

            Comment


            • #7
              I am not sure I fully understand what you want to achieve. You want to fill all the rows of xn of the same group with the weighted average of X and y (i.e price and and qt)?
              I don't think it is possible to avoid the loop completely if you are working with panel data. So the loop you have implemented is the best you can do

              If you have enough memory try to use st_data() instead of st_view(). Mata code tend to be slow(er) using views. And evalutate the number of rows of obs outside the loop, it will speed up the loop.

              Code:
              obs =panelsetup(gr,1) //grouping variable  
              nobs = rows(obs) // more efficient, takes time to evaluate rows(obs)
              for (g=1; g<=nobs; g++) { // loop through each group    
                   X=price[|obs[g,1],1 \ obs[g,2],1|]    
                   Y=    qt[|obs[g,1],1 \ obs[g,2],1|]    
                   xn[obs[g,1]::obs[g,2],1]=J(obs[g,2]-obs[g,1] + 1, 1, mean(X,Y))     }  
              end
              Last edited by Christophe Kolodziejczyk; 13 Feb 2017, 03:26.

              Comment


              • #8
                Christophe Kolodziejczyk You did it. Matrix J was the key, which I was missing. Thanks for your reply and helpful solution. Also, the additional input on the weighted mean with mean(X,Y) was a bonus.

                Comment

                Working...
                X