问题
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