Announcement

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

  • Dynamically rename variable (using "word()")

    I have a dataset that looks as follows:

    Code:
    clear
    input str7 index int data
        "EOSQ041"    42
        "EOSQ041"    13
        "EOSQ049"    17
        "EOSQ049"   210
    end
    save "my_dataset", replace
    I want to create subsets containing data from one index only, and then rename data with a user friendly title.

    I tried the following script, but I get an error on the rename command.

    Code:
    local index_considered EOSQ041 EOSQ049
    local index_considered_name public_trust transparency_gov_policimaking
    
    forvalues n = 1/`: word count `index_considered'' {
        clear
        use "my_dataset"
    
        keep if index == word("`index_considered'", `n')
        rename data word("`index_considered_name'", `n')
    }
    The next code (less clean), doesn't work neither:

    Code:
    local index_considered EOSQ041 EOSQ049
    local index_considered_name public_trust transparency_gov_policimaking
    
    forvalues n = 1/`: word count `index_considered'' {
        clear
        use "my_dataset"
    
        keep if index == word("`index_considered'", `n')
    
        local name word("`index_considered_name'", `n')
        * display `name'
        rename data `name'
    }
    Question: How to dynamically rename my variable in the loop?

    (Note: I'm using two independent local macros: one for the indexes, one for their user-friendly name. I think it would be more elegant to use one unique 2-dimensional macro, but I'm not sure it's possible with Stata...)


    Additional question: what if I now want to save my subset? The following doesn't seem to work neither

    Code:
    local index_considered EOSQ041 EOSQ049
    local index_considered_name public_trust transparency_gov_policimaking
    
    forvalues n = 1/`: word count `index_considered'' {
        clear
        use "my_dataset"
    
        keep if index == word("`index_considered'", `n')
        save "dataset_`word("`index_considered_name'", `n')'", replace
    }

  • #2
    Hi Elsa,

    I am not familiar with the word() syntax you are using, but here is one way:

    Code:
    clear all 
    input str7 index int data
        "EOSQ041"    42
        "EOSQ041"    13
        "EOSQ049"    17
        "EOSQ049"   210
    end
    save "my_dataset", replace
    
    local index_considered EOSQ041 EOSQ049
    local index_considered_name public_trust transparency_gov_policimaking
    
    forvalues n = 1/`: word count `index_considered'' {
        clear
        use "my_dataset"
        loc newvar: word `n' of `index_considered_name' 
        
        keep if index == word("`index_considered'", `n')
        rename data `newvar'
    
        save "my_dataset_`newvar'", replace
    }

    Comment


    • #3
      Using your example data, if the following is wanted:
      Code:
      . use transparency_gov_policimaking.dta
      
      . list , abbr(32)
      
           +-----------------------------------------+
           |   index   transparency_gov_policimaking |
           |-----------------------------------------|
        1. | EOSQ049                              17 |
        2. | EOSQ049                             210 |
           +-----------------------------------------+
      one solution could be:
      Code:
      ********************************************************************************
      #delim ;
      
          local pairs = 
          
          `"
              " EOSQ041 public_trust "
              " EOSQ049 transparency_gov_policimaking "
          "'
      ;
      #delim cr
      
      use my_dataset
      
      foreach pair of local pairs {
      
          preserve
      
              tokenize "`pair'"
              keep if ( index == "`1'" ) 
              rename data `2'
              save `2'
              
          restore 
      }
      ********************************************************************************

      Comment


      • #4
        Thank you Julian Duggan: using loc newvar: word `n' of `index_considered_name' instead of local name word("`index_considered_name'", `n') was the "trick" here. It does solve my initial issue.

        I'd, however, go froward with Bjarte Aagnes' solution: it's more elegant and "correct" (both tokens are defined together): using a "string of strings" coupled with tokenize is smart! Thanks also for improving my code with preserve and restore.

        Comment


        • #5
          Adding: the definition of the local pairs can be in a separate do file called by -include-
          Code:
          use my_dataset
          
          include pairs.do
          
          foreach pair of local pairs {
          
              preserve
          
                  tokenize "`pair'"
                  keep if ( index == "`1'" ) 
                  rename data `2'
                  save `2'
                  
              restore 
          }

          Comment

          Working...
          X