Announcement

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

  • Estimating an interval constraint using -nl-

    Dear Statalist:

    I recently decided I wanted to estimate a regression model with an interval constraint, one that is very similar to example #1 here: https://www.stata.com/support/faqs/s...l-constraints/

    The idea is that I want to ensure that one variable has a positive coefficient, since all available theory says that the relationship between it (let's call it Variable A) and y is direct.

    According to the code on the Stata FAQ, this code is what will do the trick:

    Code:
    nl (mpg2 = exp({lna})*price + {b}*turn + {c}), nolog // expressing A as an exponential [lna=ln(a)] and then recovering the parameter [a = exp(lna)] will force it to be positive
    
    nl, coeflegend // this is to find out what Stata is calling lna by looking in the Legend column
    
    nlcom a: exp(_b[lna:_cons]) // this exponentiates the coefficient and returns it
    This is great. Unfortunately, I have a *lot* of dummy variables and interactions in this model. I only need to set one variable to be positive. Do I have to write out every coefficient like {b}*turn or is there a way to use the factor variable i. notation and the interaction # notation while also setting the constraint for the other (linear) variable A?

    Thanks for your help in advance.

    edit to above: I should add: What I really wanted to do was to use cnsreg, but it looks like the constraints only work if I want to set variable A to a specific value. I would have liked to do something like this.

    Code:
    sysuse auto
    constraint 1 price>0
    cnsreg mpg price c.weight##i.rep78, constraint(1)

    But I got a the following error message:

    (note: constraint number 1 caused error r(111))
    And I don't know what that error is but I'm pretty sure I don't trust it.

    Best,
    Jonathan
    Last edited by Jonathan Horowitz; 20 May 2024, 11:23.

  • #2
    cnsreg won't take an inequality.

    This might help:
    HTML Code:
    https://www.stata.com/support/faqs/statistics/regression-with-interval-constraints/

    Comment


    • #3
      Thanks, that's what I had in the first part of the post. I'm still figuring out if there's a way to do that with interactions and factor variables.

      Comment


      • #4
        Sounds complicated.

        Comment


        • #5
          If you are uninterested in the dummy coefficients, you might try residual regression, filtering out the "fixed effects" before estimation.

          Or something like this (though if many, you'd have to add an if when past 26

          Code:
          sysuse auto, clear
          g mpg2 = ln(mpg)
          global X
          local i = 1
          foreach var in turn displacement weight trunk gear_ratio {
              local c : word `i' of `c(alpha)'
              local z = "{`c'}*`var'"
              di "`z'"
              global X $X + `z'
              local i = `i' + 1
              }
          nl (mpg2 = exp({lna})*price + {cons} $X ), nolog

          Comment


          • #6
            Originally posted by George Ford View Post
            Sounds complicated.
            It does! I've been searching in the -nl- documentation to see how one might write a substitutable expression that works properly. I'm not good at this sort of programming.

            This obviously doesn't work, but if there was a way to just use the expression:

            Code:
             
             exp({lna})*price
            Alongside the operators for factor variables and interactions, that would be ideal.

            Otherwise, I may have to use the xi i. expansion to create all the variables and then write something vaguely like this:

            Code:
            sysuse auto.dta
            
            rename rep78 rep
            
            xi i.rep*weight
            
            dropmiss rep weight, obs any force
            
            nl (mpg = exp({lna})*price + {b1}*weight + {b2}*_Irep_2 + {b3}*_Irep_3 + {b4}*_Irep_4 + {b5}*_Irep_5 + ///
            {b6}*_IrepXweigh_2 + {b7}*_IrepXweigh_3 + {b8}*_IrepXweigh_4 + {b9}*_IrepXweigh_5 + {c}), nolog
            
            nl, coeflegend
            
            nlcom a: exp(_b[lna:_cons])
            But this seems like a lot of work, so I'd prefer to avoid it if I can.

            Comment


            • #7
              #5 gives you a loop to create the {b}*x expressions, and then you just insert the global. But you'll have to break apart your categorical variables.

              Comment

              Working...
              X