Announcement

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

  • Local storing string content not working

    Hi, I would like to take the levels of a variable (string) in one file and use that list to loop through variables in another file. Particularly I want to do some variable transformations only to the variables in the list of that variable transformation.

    I have loaded the dataset where I need to loop through variables (do the transformations), and using preserve and restore I create the locals with the levels of the vars there. however, when I want to call this locals some few lines later, it doesn't work.

    I think the local is being created because I can see the different strings being quoted after the command creating the local, but then when calling it nothing happens. Should I call it differently if the content is a string? Or would it not work because I'm in the preserve/restore environment?
    If there's any alternative could you please let me know?

    Thanks a lot



    use "${dta_path}/dataset_raw.dta", clear

    This is the part of the code I have:

    *generate a local with the vars to be transformed for each transformation
    preserve
    import excel using "${codes_path}\havercodes_list_test.xlsx", sheet("variable_transformation") firstrow clear
    drop if var == ""
    ds var, not
    local transf `r(varlist)'
    foreach t of local transf {
    tostring(`t'), replace //to be able to replace by a string
    replace `t' = var[_n] if `t' == "1" // to make a list of vars for that transf
    levelsof `t', local(vars_`t') clean
    }
    restore


    *3y average (avg_3y) (one of the vars in the previous files is called avg_3y so a local called vars_avg_3y should have been created
    foreach v of local vars_avg_3y {
    by country_code: egen `v'_3y = filter(`v'), lags(0/12) normalise
    }

  • #2
    You have given too little detail to permit an easy diagnosis of your problem. Showing us a data example using -dataex-, which is described in the StataList FAQ for new users, would explain this for you. Lacking that, I'll offer the following guesses about potential problems:

    1) replace `t' = var[_n] if `t' == "1"
    I don't believe this if condition can ever be true. `t' contains variable names, and "1" can never be a valid Stata variable name.
    2) "It doesn't work" doesn't help us as help you. There are many ways something might not work, and we don't know which one you experienced.
    3) After your loop, the local vars_`t' will only contain whatever content it had on the *last* iteration of your -foreach- loop. Is that what you want?
    4) While the -restore- command does not destroy a local, it does eliminate any new variables created within the preserve/restore block. -restore- means "bring back exactly the file I had when the -preserve- command was issued." If you're looking for variables created in that block, they won't exist after -restore-
    5) If you're concerned about the content of a local being lost, you can debug such occurrences by inserting -display "`MyLocalName'"- command throughout your code.

    Comment


    • #3
      Hi Mike,

      Thanks a lot for your response!
      On 1) actually that part works because I initially have dummies which I transform to string and it's as saying replace for var1 the "1" with the name of the var which is stored on another variable.

      Here is what I import initially, which is a list of variables (y axis/first var) and transformations (x axis/var names) for which I have a dummy saying whether I want that transformation for that variable:
      Code:
      * Example generated by -dataex-. To install: ssc install dataex
      clear
      input str12 var byte(avg_3y chg_3y avg_1y chg_1y)
      "rgdp"         1 . 1 .
      "ca"           1 1 . .
      "reserve_adeq" . . 1 1
      "inflation"    . 1 . 1
      "reserves"     1 1 1 1
      ""             . . . .
      ""             . . . .
      end
      After running the first part of the code I end up with this (each variable/transformation type has a list of the variables which should have that transformation done):

      Code:
      * Example generated by -dataex-. To install: ssc install dataex
      clear
      input str12 var str8 avg_3y str9 chg_3y str12(avg_1y chg_1y)
      "rgdp"         "rgdp"     "."         "rgdp"         "."           
      "ca"           "ca"       "ca"        "."            "."           
      "reserve_adeq" "."        "."         "reserve_adeq" "reserve_adeq"
      "inflation"    "."        "inflation" "."            "inflation"   
      "reserves"     "reserves" "reserves"  "reserves"     "reserves"    
      end
      And here I want to create a local for each transformation/variable with the names of the variables to be transformed and here I understand the line below should do it. I'm not sure why they should be overwritten as you mention in point 3 as they will have different names, right? So for example I would have a local called vars_avg_3y with values rgdp, ca and reserves when t is avg_3y and so on for the rest. Or it doesn't work that way?

      levelsof `t', local(vars_`t') clean

      I do get the names of the vars listed, but I'm not sure that means they're being stored in the locals.

      avg_3y was byte now str1
      variable avg_3y was str1 now str8
      (3 real changes made)
      . ca reserves rgdp
      chg_3y was byte now str1
      variable chg_3y was str1 now str9
      (3 real changes made)
      . ca inflation reserves
      avg_1y was byte now str1
      variable avg_1y was str1 now str12
      (3 real changes made)
      . reserve_adeq reserves rgdp
      chg_1y was byte now str1
      variable chg_1y was str1 now str12
      (3 real changes made)
      . inflation reserve_adeq reserves

      The other dataset to which I return after creating (or trying to create) these locals is the following (shortened, it's a panel):


      Code:
      * Example generated by -dataex-. To install: ssc install dataex
      clear
      input str28 country_name int country_code str2 country_iso2 str3 country_iso3 double(quarter currency_crisis debt_crisis banking_crisis rgdp ca reserve_adeq inflation reserves)
      "Turkey" 186 "TK" "TUR" 100 0 0 0 . . . .007769999999999999 1863.62
      "Turkey" 186 "TK" "TUR" 101 0 0 0 . . . .008276666666666667 2009.85
      "Turkey" 186 "TK" "TUR" 102 0 0 0 . . . .008696666666666667  2038.5
      "Turkey" 186 "TK" "TUR" 103 0 0 0 . . . .009963333333333333 2124.64
      "Turkey" 186 "TK" "TUR" 104 0 0 0 . . . .010716666666666666 2261.81
      end
      format %tq quarter
      where rgdp and ca for example are variables to which I wish to do some transformations depending on the fact that they are part or not of the specific macros.
      So ideally if the macro was created as vars+the var name I would have a local vars_chg_1y that contains some of the vars in this new dataset. I changed a bit the last part as I realised that filter didn't work with by. But the local certainly doesn't exist because I get a message like _3y invalid name, so it's not recognising `v'.

      *3y average (avg_3y)
      foreach v of local vars_chg_1y {
      rangestat (mean) `v'_3y = `v', interval(quarter -11 -0) by(country_code)
      }


      Any other thoughts on what could be the issue?

      Thanks again!

      Comment


      • #4
        Whoops, yes, I was definitely wrong regarding `t' == 1.

        I don't have time today to dig through all the details of what you reposted here, but I can respond to one thing you said:
        "So for example I would have a local called vars_avg_3y with values rgdp, ca and reserves when t is avg_3y and so on for the rest. Or it doesn't work that way?"

        No need to wonder about that. Just put in some -display- echos in your code. That's always my first attempt at finding an error like this. So, for example, I'd do this:
        Code:
        levelsof `t', local(vars_`t') clean
        display "My local vars_`t'  =  `vars_`t''"
        You might also look at the -macro dir- command as a quick way to get a list of all the macros defined at a given point.

        Comment


        • #5
          You talk about running the first part of the code.

          I believe your problem is that you have written your code in the do-file editor window, and then rather than running everything at once, you are running it by (a) selecting the first part and running it, which creates the local macros vars_avg_vars_3y chg_3y vars_avg_1y vars_chg_1y, and then (b) selecting the next part and running it.

          Consider the following example. In the do-file editor window, I have a two-line program that I run in its entirety.
          Code:
          . do "/Users/lisowskiw/Downloads/example.do"
          
          . local message Hello, world.
          
          . display "The message is `message'"
          The message is Hello, world.
          
          . 
          end of do-file
          Now I run the same two lines by selecting the first line and running it, then selecting the second line and running it.
          Code:
          . do "/var/folders/xr/lm5ccr996k7dspxs35yqzyt80000gp/T//SD17616.000000"
          
          . local message Hello, world.
          
          . 
          end of do-file
          
          . do "/var/folders/xr/lm5ccr996k7dspxs35yqzyt80000gp/T//SD17616.000000"
          
          . display "The message is `message'"
          The message is 
          
          . 
          end of do-file
          The important thing to keep in mind is that local macros vanish when the do-file within which they were created ends. If you look carefully at the results above, you'll see that when I selected a single line to run, it was copied into a temporary do-file and run, so even though both lines are in the same window in the do-file editor, they are run as separate do-files, and local macro defined in the first line vanishes at the end of that do-file, and is undefined when the second line is run.

          So the solution is to run the entire do-file at once, not a piece at a time.

          Comment


          • #6
            Let me add that in your code there is a problem. The following is copied from post #1 with the command highlighted in red added.
            Code:
            tostring(`t'), replace //to be able to replace by a string
            replace `t' = "" if `t' == "."
            replace `t' = var[_n] if `t' == "1" // to make a list of vars for that transf
            levelsof `t', local(vars_`t') clean 
            }
            The tostring() function works literally - it formats the number as though it were to be displayed, and then saves that formatted value as a string. Thus a missing numeric value does not become a missing string value "" but instead becomes "." which is included as a "level" by the levelsof command.

            If you look carefully at the output in post #3 you'll see that the levelsof command is including the "." in its output.
            Code:
            avg_3y was byte now str1
            variable avg_3y was str1 now str8
            (3 real changes made)
            . ca reserves rgdp

            Comment


            • #7
              Perfect! thank you very much everyone for the comments to the code and more general information which is very useful. Replacing the missing for the "" works fine and then the code runs fine! thanks a lot

              Comment

              Working...
              X