如何使用forval循环并考虑一个例外?

时间:2018-11-13 22:25:04

标签: stata

我有900个文件,其中包含名为v1 – v1000的1,000个变量,还有1个文件,其中包含名为v1 – v43的43个变量。

我在Stata中的代码最初使用foreach循环打开每个文件,该循环导入文件,同时擦除每个文件的第一行(此处未显示)。

然后,我使用这个嵌套的forval循环来重命名变量:

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

此代码无法正常运行,因为我的上一个文件没有名为v44 – v1000的变量。

我需要一个代码片段,该代码片段可以读取前1,000个文件的900变量和最后一个文件的43变量。我尝试使用c(k)(即在循环之前计算每个文件中的变量数量):

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

但是,这不起作用。有什么建议吗?

2 个答案:

答案 0 :(得分:3)

使用一些人工生成的数据集:

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

这是一个例子:

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
}

在下面您可以看到结果:

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 |
     +-----------------------------------------------+

答案 1 :(得分:1)

一种非常简单但不太优雅的方法是使用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
}