Announcement

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

  • Sum Over Negative Observations of a Column

    I am calling mata in a stata do file. The following code sums over the columns in matrix A. Is there a way to only sum over negative entries?

    mata : st_matrix("B", colsum(st_matrix("A")))

    So:

    A = [1 2; -2 -2; -3 -1]
    B = [-5 -3]

  • #2
    You can do something like the following. I've spelled it out so that you can see the intermediate results, but you can condense the code in obvious ways. There might even be a function or two already built into Mata to do some of the wrangling more compactly; I'm often amazed to discover on the List what's available there.

    .ÿsetÿlinesizeÿ72

    .ÿmata:
    -------------------------------------------------ÿmataÿ(typeÿendÿtoÿexit
    >ÿ)ÿ--------------------------------------------------------------------
    :ÿAÿ=ÿ1,ÿ2ÿ\ÿ-2,ÿ-2ÿ\ÿ-3ÿ,ÿ-1

    :ÿSelectÿ=ÿA:<0

    :ÿSelect
    ÿÿÿÿÿÿÿ1ÿÿÿ2
    ÿÿÿÿ+---------+
    ÿÿ1ÿ|ÿÿ0ÿÿÿ0ÿÿ|
    ÿÿ2ÿ|ÿÿ1ÿÿÿ1ÿÿ|
    ÿÿ3ÿ|ÿÿ1ÿÿÿ1ÿÿ|
    ÿÿÿÿ+---------+

    :ÿCÿ=ÿAÿ:*ÿSelect

    :ÿC
    ÿÿÿÿÿÿÿÿ1ÿÿÿÿ2
    ÿÿÿÿ+-----------+
    ÿÿ1ÿ|ÿÿÿ0ÿÿÿÿ0ÿÿ|
    ÿÿ2ÿ|ÿÿ-2ÿÿÿ-2ÿÿ|
    ÿÿ3ÿ|ÿÿ-3ÿÿÿ-1ÿÿ|
    ÿÿÿÿ+-----------+

    :ÿBÿ=ÿcolsum(C)

    :ÿB
    ÿÿÿÿÿÿÿÿ1ÿÿÿÿ2
    ÿÿÿÿ+-----------+
    ÿÿ1ÿ|ÿÿ-5ÿÿÿ-3ÿÿ|
    ÿÿÿÿ+-----------+

    :ÿend
    ------------------------------------------------------------------------

    .

    Comment


    • #3
      What do you want to happen if a row contains a mix of positive and negative values?

      Joseph's code can be collapsed to

      Code:
      : A = (1, 2 \ -2, -2 \ -3, -1)
      
      : colsum((A :< 0) :* A)
              1    2
          +-----------+
        1 |  -5   -3  |
          +-----------+

      Comment


      • #4
        Assuming you only want rows that are entirely negative, you can use the select function:

        Code:
        colsum( select(A, rowsum(A :< 0)) )
        If you want at least one column to be negative then use rowsum(A :< 0) >= 1 in the second argument to select.

        If you want each column treated independently, then the matrix multiplication approach works.

        Comment


        • #5
          Frank: That condition selects rows with any values negative, and not exclusively those with all values negative. The rowsum is positive with just one negative value.

          Comment


          • #6
            Doh, you're right, thanks Nick Cox

            Comment


            • #7
              Thank you, Joseph and Nick. That works beautifully.

              Comment

              Working...
              X