Announcement

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

  • Can Stata evaluate expressions on the fly?

    I have the following little loop that works. Before creating the macro var "curvar" (which works in the next expression to add a label to a variable), I was trying to add the -word("`symbol'", `j')- to the label command [label var word("`symbol'", `j') "`I'"] and getting all kinds of syntax errors.

    Is it possible in Stata to evaluate such expressions as the word() function within the code without having to create the macro var? In some coding languages there are functions such as eval(), etc. that can evaluate the expression within the code. I was wondering if such a thing exists in Stata.

    *put labels on vars
    local j=0
    foreach i in "`lblnam'" {
    local ++j
    local curvar=word("`symbol'",`j')
    label var `curvar' "`i'"
    }

  • #2
    You can force the evaluation using macro quotes and a leading equal sign.

    Code:
    `=word("`symbol'", `j')'

    Comment


    • #3
      My guess is that the problem in #1 would be much easier to address if we had much more context and a reproducible example.

      Comment


      • #4
        Thanks. The nine items in "symbol" are the var names in the dataset. The 9 items in "lblnam" are the labels to be added to the cryptic var names in the same orders. The dataset contains these var names with historical price data for each. I'm just adding labels to easily explain the short, cryptic var names. Previous loops in the code create the vars and populate them with the historical data. I'm adding the labels after the dataset is created because I didn't think about it when creating the vars. Let me know if you need additional data.

        I'm trying to set up the code for these products because I have more sets of products that I'm hoping to be able to use the same code with changes only in product names.

        local symbol aud gbp brl cad chf eur jpy mxn nzd
        local lblnam "Australian Dollar" "British Pound Sterling" "Brazilian Real" "Canadian Dollar" "Swiss Franc" "Euro" "Japanese Yen" "Mexican Peso" "New Zealand Dollar"

        *put labels on vars
        local j=0
        foreach i in "`lblnam'" {
        local ++j
        local curvar=word("`symbol'",`j')
        label var `curvar' "`i'"
        }

        Comment


        • #5
          Thanks much for the detail.

          There's no disgrace in just writing out 6 command lines such as

          Code:
          label var aud "Australian dollar"
          as that is less code, much easier for most readers to grasp, and easier too for the programmer to write and maintain.

          I would say the same for 60 currencies even!

          Looping in your case is about as tricky as possible given a problem simple in principle. One challenge is a need to wrestle with compound double quotes too, unless I am missing something. .

          I got this to work:

          Code:
          clear 
          set obs 1 
          
          local symbol aud gbp brl cad chf eur jpy mxn nzd
          tokenize `" "Australian Dollar" "British Pound Sterling" "Brazilian Real" "Canadian Dollar" "Swiss Franc" "Euro" "Japanese Yen" "Mexican Peso" "New Zealand Dollar" "'
          
          local j = 1 
          foreach v of local symbol { 
              gen `v' = 42 
              label var `v' `"``j''"'
              local ++j 
          }
          
          describe
          Code:
          . describe 
          
          Contains data
           Observations:             1                  
              Variables:             9                  
          ---------------------------------------------------------------------------------------
          Variable      Storage   Display    Value
              name         type    format    label      Variable label
          ---------------------------------------------------------------------------------------
          aud             float   %9.0g                 Australian Dollar
          gbp             float   %9.0g                 British Pound Sterling
          brl             float   %9.0g                 Brazilian Real
          cad             float   %9.0g                 Canadian Dollar
          chf             float   %9.0g                 Swiss Franc
          eur             float   %9.0g                 Euro
          jpy             float   %9.0g                 Japanese Yen
          mxn             float   %9.0g                 Mexican Peso
          nzd             float   %9.0g                 New Zealand Dollar
          ---------------------------------------------------------------------------------------
          Sorted by: 
               Note: Dataset has changed since last saved.
          More discussion at https://journals.sagepub.com/doi/pdf...6867X211063415

          Comment


          • #6
            Naturally there are 8 currencies in the problem, not 6.

            Here is another way to do it. Clearly I need to generate variables; otherwise I can't assign variable labels. But in your case they already exist.

            The paper linked in #2 remains germane.

            Code:
            clear 
            set obs 1 
            
            local symbol aud gbp brl cad chf eur jpy mxn nzd
            local labnam `" "Australian Dollar" "British Pound Sterling" "Brazilian Real" "Canadian Dollar" "Swiss Franc" "Euro" "Japanese Yen" "Mexican Peso" "New Zealand Dollar" "'
            local nv : word count `symbol'
            
            forval j = 1/`nv'  { 
                gettoken v symbol : symbol
                gen `v' = 42 
                gettoken lbl labnam : labnam 
                label var `v' `"`lbl'"'
            }

            Comment


            • #7
              Andrew Musau thanks. Yes, that seems to work to resolve the expression within the code.

              Comment


              • #8
                Nick Cox, yes that method works. I've had to look up some of those commands as I've only used Stata for about a month (hence, my monitoring of this forum). But, I've coded in SAS and recently Python for many years. I'm retired so no one will be using my code except me, so I am only concerned about its readability and documentation to satisfy my need to remember what things are doing. The tokenize command and subsequent references are interesting. I see the command:
                label var `v' `"``j''"' to be interesting. If I understand correctly, the 2 macro quotes around j makes it resolve j first as a numeric, then second it resolves the numeric macro var that is created by the "tokenize" command. If you don't mind me asking, I see in several places that you put macro quotes (` and ') on the "outside" of the double quotes. It seems to me it works fine without those outside macro quotes. What is the point of using those outside macro quotes? As mentioned, I'm on a steep learning curve with Stata coding methods and commands.

                Comment


                • #9
                  I see in several places that you put macro quotes (` and ') on the "outside" of the double quotes. It seems to me it works fine without those outside macro quotes. What is the point of using those outside macro quotes?
                  The configuration `" whatever "' is called compound double quotes. You can read about them in the Users Guid section of the PDF documentation that is installed with your Stata. They exist, and should be used, whenever whatever might, itself, contain quotation marks. The problem with ordinary quotation marks is that if you have something like "abc"def"ghi", it isn't clear whether you are quoting abc, then listing def, and then quoting ghi, or if you are quoting abc"def"ghi. That's because unlike parentheses, brackets, and braces, the opening delimiter and the closing delimiter of quotation marks are exactly the same. Yes, in some software, there are "smart quotes" where an opening quotation mark looks like a little 99 and the closing one looks like a little 66. But Stata doesn't have those. And if you try to nest a quotation inside of a quotation, Stata will get very confused. Compound double quotes were meant to solve this problem: `" does not look the same as "'. So Stata can easily distinguish `"abc"'def`"ghi"', two quoted strings surrounding an unquoted one, from `"abc`"def"'ghi"', where quoted def is nested inside quoted abc...ghi.

                  If you are just using strings like "yes", "no", "John", etc., and you won't be nesting quotes inside quotes, then you do not need to use compound double quotes: the ordinary quotes work just fine. But when you are writing code and you are putting quotes around macros, e.g. in `"`x'"', if there is any possibility that the content of `x' can contain quotes, it is safer to use the compound double quotes.
                  Last edited by Clyde Schechter; Today, 18:59.

                  Comment

                  Working...
                  X