Announcement

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

  • Commands work but identical commands in a program don't, why?


    Hello, I am trying to understand why the first set of code works: Just copy the code between "this works", select, and run in a do file to use....
    but the seemingly identical code in a program block, selected, and run in a do file doesn't work. Any explanation of why would be greatly welcome.

    The intended outcome is:

    Code:
    . di "`list1' `list2' `list3'"
    (len_start1[ m ] != 10)
    and

    Code:
    . forval f = 1/3 {
      2.   di "`list`f''"
      3. }
    (len_start1[
    m
    ] != 10)

    Code:
    
    **************** this works (put in do file, select, and run)  ***************
    clear all
    
    local list1 "(len_start1["
    local list2 "m"
    local list3 "] != 10)"
    
    di "`list1' `list2' `list3'"
    di "`list2'"
    
    forval f = 1/3 {
      di "`list`f''"
    }
    ********************************************
    
    
    *********** this doesn't work (put in do file, select, and run) *************
    clear all
    capture program drop test
    program test
        args list1 list2 list3
    
    di "`list1' `list2' `list3'"
    forval f = 1/3 {
      di "`list`f''"
    }
    end
    
    local list1 "(len_start1["
    local list2 "m"
    local list3 "] != 10)"
    
    test `list1' `list2' `list3'
    ******************************************

  • #2
    When you pass

    `list1' `list2' `list3'

    to a program that program never sees and so cannot use the original distinct identities of each macro. It just sees the concatenation of those macros.

    If list1 is a b c for example then those are the first second third arguments identified by your args command and everything else in the other macros is ignored.

    Otherwise put, args uses parsing by spaces, only, unless you pass " " to the program to delimit each macro.

    Comment


    • #3
      Thanks Nick, I think I was confusing this post by calling the args list1...list3 as well as the local macros list 1 2 3. That was not necessary. Reformatting to this by dropping the [m] part and I think I can get it to do what was intended:

      Code:
      capture program drop test
      program test
          args a1 a2 a3 
      
      di "display all three:  `a1' `a2' `a3'"
      forval f = 1/3 {
        di "`a`f''"
      }
      count if `a1'[137] `a2' `a3'
      
      end
      
      local list1 "(len_start1"
      local list2 "!="
      local list3 "10)"
      
      test `list1' `list2' `list3'

      What I was trying to do ideally was to pass an if statement into the program...like:

      Code:
      local myif  `" "(len_start1["  "m"  "] != 10)" "'
      or
      Code:
      local myif  `" " pid == -8 | pid == -9 | pid ==." "'
      and then when it gets in the program could do:
      Code:
      if `myif'
      ...but that wasn't working...and it seems impossible to pass a full string.. particulary one that contains [`m'] into a program.

      Or..even better...if I could pass a local that contained a LOT of if statements.... but I've given up on that as impossible with STATA. Would be easy with most programming languages, as escape characters for strings work properly, but in STATA the special use of " ` ' [ ] and so forth seems to make it not possible.

      Not sure if I've made any sense there...so apologies if not. Any hints where to look to resolve the ideal goal welcome...but not expected.


      Comment


      • #4
        Not a good idea to call your program test when there already is a test command in Stata. Anyways, here is the standard way of passing if-expressions:

        Code:
        program mytest
            
            syntax varlist [ if ]
            
            marksample touse
            
            ... if `touse'
            
        end

        You then use standard Stata syntax to call your program

        Code:
        mytest varname if pid == -8 | pid == -9 | pid == .
        For more information, see

        Code:
        help syntax
        help mark
        If you want something else, please explain exactly what it is you want; preferably with reproducible minimal data examples.

        Comment


        • #5
          Originally posted by L Rainen View Post
          [...]
          What I was trying to do ideally was to pass an if statement into the program
          Seems like a case of XY Problem to me.

          Comment


          • #6
            I agree with daniel klein

            Stata sometimes uses more or less standard ideas and sometimes has ideas of its own, so looking for the equivalent of what you know already can lead to frustration if it doesn't exist or is hard to implement.

            Experience with other languages can help mightily -- and hinder too. I started in Stata after a complicated period over about 20 years of messing around in various mainstream languages and in various more or less programmable statistical languages or environments. So ideas like looping were familiar, but Stata's macro language was weird to get used to. Now I don't have call to program in anything else.

            I have seen the opposite: that people writing programs in Stata get used to Stata and then when they also use another environment want Stata's features. So far, so fine, but the answers sometimes disappoint. I've seen questions like what is the equivalent of egen in X? to which the short answer is that there isn't one and a longer answer is that egen exists for partly esoteric reasons but that there is absolutely no reason to re-invent it in X (regardless of what X is). So even if one appreciates egen within Stata as a useful toolkit something else entirely is needed to the same things.

            This comment is meant to be explanatory and not judgemental. There are some wonderful languages out there, and given 48 hours in the day I would want to try several!

            Comment

            Working...
            X