Announcement

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

  • local macros involving string text

    Hello Statalisters,

    I apologize if this has been addressed elsewhere -- I've been working on this problem off and on for several weeks and (I think) have reviewed all posts and manual sections that touch on the issue I'm having, without success

    I'm in stata 14.2, and for months have been having trouble getting any local containing text to work. For example, I try to write a local to define my cd, as follows
    Code:
    local ddir "C:\Users\blablabla"
    But when I type
    Code:
    Code:
    di `ddir'
    nothing happens

    I've worked around this till now.
    I now have a survey with several questions in a matrix, all with the same yes/no response options (yes =1, no = 2). It looks something like this:

    If you went to the grocery store today, would you
    1) buy eggs, yes/no
    2) buy butter, yes/no
    3) buy vegetables, yes/no

    Currently, variable representing question 1 is v_1, var representing question 2 is v_2, etc.
    I want to write a loop that renames all of these variables "grocery_eggs", "grocery_butter", etc

    I tried the following code, based on a prior post on this topic:

    Code:
    label define yesno 1 "Yes" 2 "No"
    local grocery "eggs butter veg"
    local n : word count `grocery'
    
    foreach var of varlist v_1-v_3     {
         gen `var'l = `var'
         label values `var'l yesno
         forvalues i = 1/`n'
              local a: word `i' of `grocery'
              label `var'l "grocery_"`a'
              }
         }
    It doesn't work, and when i troubleshot by trying
    Code:
    di `grocery'
    , the same thing happened as above -- nothing displayed
    I tried double quotes in both the local definition, ie
    Code:
    local grocery "`eggs butter veg'"
    and
    Code:
    local grocery `"eggs butter veg"'
    as well as in the display command involving the local with string, ie
    Code:
    di `"grocery"'
    and
    Code:
    di "`grocery'"
    and neither worked

    I am doing the entirety of the above code in the same do-file during the same session, so this shouldn't be a problem with stata not recognizing the local when I type the display commands

    Thank you very much in advance!
    -Beth

  • #2
    A local is exactly that, a local. It ceases to exist after the code has run. So typing -di `mylocal'- afterwards is never going to display anything.

    You say your code "doesn't work", but don't report what doesn't work about it. Do you get errors? Does it not do what you want?

    This is probably the problem:

    Code:
     local n : word count `grocery'

    but who knows? Try putting
    Code:
       di `n'  "   `grocery'"

    right after that statement, to see what is in -n- and what is in -grocery- hth, Jeph

    Comment


    • #3
      Your local macros n and grocery are fine. There is no problem with them.

      You also have a sysntax error when you say -label `var'l "grocery_"`a'- It should be -label var `var'l "grocery_"`a'-

      The nested foreach and forvalues loops are syntactically OK, assuming you have variables named v_1-v_3. But the inner loop makes no sense. It will, in the end, label all of the variables v_1l, v_2l, and v_3l grocery_veg. That's because the -forvalues- loop, being inside the -foreach loop- is applied to each of those three variables, and it labels each of them, initially, grocery_eggs, but then overwrites that label with grocery_butter, and, finally, with grocery_veg.

      My guess is that what you want is to label v_1l grocery_eggs, v_2l grocery_butter, and v_3l grocery_veg. That requires a somewhat different logic. In fact, if the variables really are named v_1, v_2, and v_3, then it really is just a simple single loop:

      Code:
      forvalues i = 1/3 {
          gen v_`i'l = v_`i'
          label values v_`i'l yesno
          local a: word `i' of `grocery'
          label var v_`i'l "grocery_`a'"
      }
      Do heed Jeph's good advice: when working with code involving local macros you must run it all at once. If you run a line or a block that defines macros, they disappear after the block runs, and then are not available in a later block that refers to them. So all of the code involving them must run at once.

      Do heed Jeph's other good advice: when asking for help troubleshooting code, saying "it doesn't work" is not helpful to those who want to help you. You need to say what you did (or, better still, show the exact code you tried), then show the exact output you got (including any error messages, results), and then, if it is not obvious, explain why it isn't what you were hoping for.

      Comment


      • #4
        You seem confused on what you want, as your text says that you want to rename, but your code would assign variable labels if it worked.

        Code:
        rename (v_1 v_2 v_3) (grocery_eggs grocery_butter grocery_veg)
        is as good as any other solution for your example if the problem is to rename.

        As your question is about locals and loops also, here is another way to do it. It hinges -- as given here, and like Clyde's solution -- on each distinct new piece of text being a single word. But that often happens, and in each case the solution can be extended to cover multiple words.

        This example adds small but useful twists: The variables are 0, 1 indicators. In Stata you're much better advised to use such indicators. Further, in variable labels you don't need ugly underscores.

        Code:
        * sandbox 
        clear 
        set obs 1 
        forval j = 1/3 { 
            gen v_`j' = real(word("1 0 1", `j')) 
        }
        
        * the problem 
        label define yesno 1 "Yes" 0 "No"
        local grocery "eggs butter veg"
        
        foreach var of varlist v_1-v_3 {
             gen `var'1 = `var'
             label values `var'1 yesno
             gettoken this grocery : grocery 
             label var `var'1 "grocery: `this'" 
         }
        
         * results 
          list 
        
             +--------------------------------------+
             | v_1   v_2   v_3   v_11   v_21   v_31 |
             |--------------------------------------|
          1. |   1     0     1    Yes     No    Yes |
             +--------------------------------------+
        
        describe 
        
        Contains data
          obs:             1                          
         vars:             6                          
         size:            24                          
        ------------------------------------------------------------------------------------------
                      storage   display    value
        variable name   type    format     label      variable label
        ------------------------------------------------------------------------------------------
        v_1             float   %9.0g                 
        v_2             float   %9.0g                 
        v_3             float   %9.0g                 
        v_11            float   %9.0g      yesno      grocery: eggs
        v_21            float   %9.0g      yesno      grocery: butter
        v_31            float   %9.0g      yesno      grocery: veg
        ------------------------------------------------------------------------------------------


        Comment


        • #5
          Thank you all so much for your help and feedback. Your suggestions solved my problem.

          I apologize for the confusion on the following:
          - You are absolutely right, I was trying to apply variable labels, not rename.
          - The error I was getting before in both cases was a syntax error r(198), which seemed so nonspecific I did not even think to include it when describing the problem.
          - You are also absolutely right, I did not realize that local macros had to be run at the same time as all code referring to them -- that solves a lot of problems I was having!

          I also really appreciate learning about gettoken -- I did not know that command, and it seems VERY useful!

          Thanks again,
          Beth

          Comment

          Working...
          X