Announcement

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

  • Converting old nlfcn program to newer nl function evaluator program

    Dear Statalist community,

    I am using StataSE 16 (64-bit) on Windows 10. I am wanting to convert nl hockey (a user-written command by Dr Mark Lunt) from the old nlfcn programming style to a newer nl function evaluator program. Dr Lunt's ado file can be viewed here: https://personalpages.manchester.ac....t/nlhockey.ado

    I am struggling to get it right. Please see my attempt below to convert this.

    Code:
    capture program drop nlhockeynew
    program define nlhockeynew 
    
    {
      version 16.0
    
      syntax anything if [aw fw iw], at(name) [others]
    
      tokenize `anything'
      local first `1'
      macro shift
      local second `1'
      macro shift
      local others `*'
      local varcount 0
      if "`others'" ~= "" {
         local varcount     : word count `others'
      }
      local counter = 1
      while `counter' <= `varcount' {
        local thisvar : word `counter' of `others'
         local xbother `xbother' + \$`thisvar'*`thisvar'
        local counter = `counter' + 1
      }
    //  if "`first'" == "?" {
        
         tempname breakpoint slope_l slope_r cons
    //     global S_1 breakpoint
         scalar `breakpoint' = `at'[1, 1]
    //     global S_1 $S_1 slope_l
         scalar `slope_l' = `at'[1, 2]
    //     global S_1 $S_1 slope_r
         scalar `slope_r' = `at'[1, 3]
    //     global S_1 $S_1 `others' cons 
         scalar `cons' = `at'[1, 4]
         tempvar min max
         egen `min' = min(`second') `if'
         egen `max' = max(`second') `if'
         scalar `breakpoint'    = (`max' + `min') / 2
        regress `e(depvar)' `second' [`weight'`exp'] `if' & `second' < `breakpoint'
         tempname b
         matrix `b' = e(b)
         scalar `cons' = `b'[1,2]
         scalar `slope_l' = `b'[1,1]
         regress `depvar' `second' [`weight'`exp'] `if' & `second' > `breakpoint'
         matrix `b' = e(b)
         scalar `slope_r' = `b'[1,1]
        if "`eps'" == "" {
            tempname eps
            scalar `eps'    = (`max' - `min') / 100
         }
         local counter = 1
         while `counter' <= `varcount' {
            local thisvar : word `counter' of `others'
            global `thisvar' = 1
          local counter = `counter' + 1
         }
    //     exit
    //  }
      local x1     = `breakpoint' - `eps'
      local x2     = `breakpoint' + `eps'
      local b      = (`x2' * `slope_l' - `x1' * `slope_r') / (`x2' - `x1')
      local cc     = (`slope_r' - `b') / (2*`x2')
      local a      = `cons' + `slope_l'*`x1' - `b'*`x1' - `cc'*(`x1'^2)
      local alpha2 = (`a'  + `b'*`x2' + `cc'*(`x2'^2))-`slope_r'*`x2'
    
      replace `first' = `cons'  + `slope_l'*`second' `if' & `second' < `x1'
      replace `first' = `alpha2' + `slope_r'*`second' `if' & `second' > `x2'
      replace `first' = `a' + `b'*`second' + `cc'*`second'^2 `if' & `second' >= `x1' & `second' <= `x2'
      replace `first' = `first' `xbother' `if'
    
    }
    end
    There are several issues that crop up when I try to run this. The first is a seemingly endless run through the initial iteration (Iteration 0), which when I break it returns the error "nl returned 198". I am also unsure how what would have been the "query call" section of the code from the original program (if "`first'" == "?") fits into the newer nl programming style.

    If anyone has any thoughts on how Dr Lunt's nl hockey may be converted to the newer nl programming style, I would be very grateful. Many thanks.

  • #2
    Some code that can be used to generate an example dataset is given below:

    Code:
    use https://stats.idre.ucla.edu/stat/stata/faq/talk, clear
    expand 2
    sort id
    by id: gen obs = _n
    replace talk = talk + .8474287 if obs == 2 & age <= 11.35291
    replace talk = talk + 3.974196 if obs == 2 & age > 11.35291
    replace age = age + 1 if obs == 2
    The original nl hockey program would then be ran as:

    Code:
    nl hockey talk age
    The converted program I have tried to write (which won't run) is then:

    Code:
    nl hockeynew @ talk age, parameters(breakpoint slope_l slope_r cons)
    For more information on the old nlfcn programming style, see:

    Code:
    rnethelp "https://www.stata.com/stb/stb7/sg1_2/nl.hlp"
    ... and for the newer nl:

    Code:
    help nl
    For further information on nl hockey, it may be worth referring to a previous post of mine regarding a separate issue: https://www.statalist.org/forums/for...tandard-errors

    Comment

    Working...
    X