Announcement

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

  • A Question about confirm and _rc

    Hi All,

    I am trying to build a Stata package which can convert a numeric variable to a string variable. I tried using the code below and got the error message of: " invalid name r(198);

    Appreciate your help!

    ---

    syntax varname


    confirm str variable `varname'

    if !_rc {
    tostring "`varname'", replace
    }

  • #2
    The extra quotes ("...") around `varname' should not be there. It should be just -tostring `varname', replace-.

    Comment


    • #3
      Originally posted by Clyde Schechter View Post
      The extra quotes ("...") around `varname' should not be there. It should be just -tostring `varname', replace-.
      Hi Clyde, thank you for responding. I have removed the quotes around varname, but encountered another error:

      '' found where varname expected
      r(7);

      Comment


      • #4
        This one is coming from -confirm str variable `varname'-. That is not valid syntax. Even though your -syntax- command specifies a varname, within the body of the program you must refer to it as `varlist'. When you have -confirm str variable `varname'-, because no local macro varname has been defined, Stata reads this as -confirm str variable-, and with no variable name provided, that is a syntax error.

        Now, there is another problem here. The logic of the program is deficient. Let's look at what -confirm str variable `varlist'- (the correction you should make to that command so that it is syntactically OK) actually does. Suppose the variable you call the program with is, in fact, a string variable. Then -confirm- will find its condition satisfied, and so _rc will be 0. So the -if- command's condition !_rc is satisfied and the -tostring- command is executed. But as it is already a string variable, -tostring- will leave it as is and give you a message saying just that. On the other hand, if the program is called with a numeric variable, then -confirm- will find its condition to not be satisifed, so _rc will be 7. And, since _rc is non-zero, execution will break with an error message--you never even reach the -if- command.

        I think the programming idiom you are trying to capture, using -confirm- and _rc begins with -capture confirm...-. That way when the -confirm- condition is not satisfied, _rc is set to a non-zero value, but execution does not break and the value of _rc can be interrogated in the subsequent -if- command. So a version of this that will run without any errors is:
        Code:
        program define demo
            syntax varname
            capture confirm str variable `varlist'
            if !_rc {
                tostring `varlist', replace
            }
            exit
        end
        However, it doesn't actually do anythinng. If the variable supplied by the caller is a string variable, we have already noted that -tostring- has nothing to do: it's already string. If the variable supplied by the caller is numeric, then the -confirm- condition fails and _rc is set to 7. -if !_rc- now finds that _rc is non-zero (hence true as a boolean expression). So !_rc is false, so the -tostring- command is skipped and nothing is done. You can see how this plays out by running the following:
        Code:
        capture program drop demo
        program define demo
            syntax varname
            capture confirm str variable `varlist'
            if !_rc {
                tostring `varlist', replace
            }
            exit
        end
        
        sysuse auto, clear
        des mpg make
        demo make
        demo mpg
        des mpg make
        I'm guessing that what you are trying to do with this code is check if the variable in the calling command is a string variable, and if it isn't, convert it to string. In that case, the logical approach would be to change the -confirm- statement to -capture confirm numeric variable `varlist'-.


        Comment


        • #5
          The big picture here is tostring will leave string variables unchanged and otherwise attempt to change any other arguments, which can only be numeric variables, to string. So even in spirit the program is just adding a needless wrapper to an existing command,

          Comment


          • #6
            Doesn't a single command:

            Code:
            tostring *,replace
            do the job without a macro, loop or test? In a quick trial, -tostring- returned "var already string; no replace" for numeric variables and kept the return code (_rc) to zero. I admit to doing it the long way myself, but I suspect that isn't necessary.

            Comment


            • #7
              #6 == #5, except for a typo, I think

              Comment

              Working...
              X