How to use a forval loop and take into account one exception?

断了今生、忘了曾经 提交于 2020-01-16 18:15:09

问题


I have 900 files that include 1,000 variables named v1 – v1000 and 1 file that includes 43 variables named v1 – v43.

My code in Stata initially opens each file using a foreach loop that imports the files while erasing the first line for each file (not shown here).

Then, I use this nested forval loop to rename variables:

forval j = 1/1000 { 
    local varname = strtoname(v`j'[1])  
    rename v`j' x`varname' 
}

This code doesn’t work well because my last file doesn’t have the variables named v44 – v1000.

I need a code snippet that can read 1,000 variables for the first 900 files and 43 variables for the last file. I tried with c(k) (i.e. counting the number of variables in each file before looping):

forval j = 1/ `c(k)' {
    local varname = strtoname(v`j'[1]) 
    rename v`j'  x`varname'
}

However, this doesn’t work. Any suggestions?


回答1:


Using some artificially-generated datasets:

forvalues i = 1 / 10 {
    clear
    set obs 5
    forvalues j = 1 / 10 {
        generate v`j' = rnormal()
    }
    save data`i', replace
}

use data10, clear
drop v5-v10
save data10, replace
clear

Here's an example:

local allfiles: dir . files "*.dta"

foreach dta in `allfiles' {
    use `dta', clear
    ds v*
    local i 0
    foreach var in `r(varlist)' {
        local ++i
        rename `var' x`i'
    }
    save `dta', replace
}

Below you can see the results:

use data1, clear
list
      +-----------------------------------------------------------------------------------------------------------------------+
     |        x1          x2          x3          x4          x5          x6          x7          x8          x9         x10 |
     |-----------------------------------------------------------------------------------------------------------------------|
  1. | -.0658037     1.01091    .4984255   -.1489926   -.8711151   -2.013461    .2881269    .1096137   -1.400732   -.9703687 |
  2. |  2.389028   -1.537572   -.3862164   -.6072646   -2.262745    1.315605    1.686188   -.5404406    1.078409    -.117408 |
  3. | -.2777171    .6730747   -.5674241    -.578813   -.8116008   -.5623083    .7675297   -1.117687   -1.196418     .417776 |
  4. |  2.109452   -1.035937    2.063489    1.183948   -.5243855   -1.020852   -.8674071   -.3530601   -.1752301    1.556753 |
  5. |  .7309901   -.6810378   -.9365283    1.818035    .0232499    2.533621   -.5896646    .5805199    .1430279   -1.926774 |
     +-----------------------------------------------------------------------------------------------------------------------+

use data10, clear
list

     +-----------------------------------------------+
     |        x1          x2          x3          x4 |
     |-----------------------------------------------|
  1. | -.1145661    1.830756    1.860386    .3472159 |
  2. |   1.10806   -.5629539    1.028942   -.7665766 |
  3. |  1.269463   -1.433527   -.6405479    .8663427 |
  4. |  .0158674     1.49529    2.840101   -.9815945 |
  5. |  .0969952   -.0885036   -2.036327   -.2538646 |
     +-----------------------------------------------+



回答2:


A very easy, not very elegant method would be to check whether the variable exists with capture:

foreach dta in `allfiles' {
    use `dta', clear
    forval j = 1/1000 { 
         local varname = strtoname(v`j'[1])  
         cap confirm variable v`j'
         if (_rc == 0) rename v`j' x`varname' 
    }
    save `dta', replace
}


来源:https://stackoverflow.com/questions/53290438/how-to-use-a-forval-loop-and-take-into-account-one-exception

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!