How to manipulate filenames with a macro - loops

I want to save the results of my Stata forvalues loop into individual files. One component of the filename should be the value j assigned to the macro within a forvalues loop.
Apparently my code leads to an instruction always to save with 1995. As such, I get messages telling me that this file already exists.
I am using the following code:
local j = 1995
forvalues `j'= 1995 / 2012 {
clear
use "/Users/carl/Desktop/STATA/Neustart/eventdates.dta", clear
keep if eventyear == `j'
sort acq_cusip eventdate
compress
save "/Users/carl/Desktop/STATA/Neustart/eventdates_`j'.dta"
}
Does anyone have an answer to that?

In your original code Stata sees `j' inside the forvalues command (instead of the correct j), so it starts to evaluate that before it starts the loop. So what is eventually run is
forvalues 1995=1995/2012 {
This means that forvalues is changing the content of the local macro confusingly but legally called `1995' to 1995 in the first iteration, 1996 in the second iteration, etc. So when you refer to the local `j' inside the loop, it will not have changed and remains at the original value which you defined before the loop.
The way to solve this is to replace:
local j = 1995
forvalues `j' = 1995/2012 {
with:
forvalues j = 1995/2012 {

use replace
save "/Users/carl/Desktop/STATA/Neustart/eventdates_`j'.dta",replace
Updated
cd "C:\Users\Vista\Desktop\Stataproject"
forvalues j=1/5 {
sysuse auto,clear
keep if rep78== `j'
save "auto_`j'.dta",replace
}
Example with auto data in Stata . For details please see, Speaking Stata: How to face lists with fortitude

Related

Stata: Generate Variable with foreach

I want to aggregate my variables A1,.., A5 by creating a new variable A that is equal to A1,..,A5 whenever the corresponding r`k' is equal to 1. I have too many variables that I want to aggregate like this way and I was wondering maybe is there a way to write it more compactly than my code below. (I'm guessing that foreach can be used here but I'm not sure how)
gen A=.
gen B=.
forvalues k=1/5 {
replace A=A`k' if r`k'==1
replace B=B`k' if r`k'==1
}
This maps one loop into two:
foreach v in A B
gen `v' = .
forvalues k=1/5 {
replace `v' = `v'`k' if r`k'==1
}
}
But perhaps your data structure needs revisiting, so that instead of looping twice you could get something else more simply. So, if it makes sense, stacking A B whatever into one variable would remove one loop.

Storing structural break points with "foreach" loop in stata

read.csv("C:\Users\easy\Desktop\workbook.csv")
I need to estimate the structural breakpoint of regression over a list of countries in my dataset and I need to store these breakeven points for each country I have and display these breakeven points in a table form once the loop finishes. My dataset is panel data that is why I need to loop over the countries.
I estimate the regression for each country in my countrynum variable of countries' list. And I try to store the breakeven point for each country regression estimation as follows
foreach i in countrynum {
by countrynum, sort: reg y x1 x2 x3 if `i'== countrynum
est store `r'(breakdate)
}
Stata is returning the following error message:
( invalid name
) invalid name
r(7);
Any idea what is wrong with my code?
Assuming the syntax fixes that Nick Cox aptly laid out, what you are missing is sbsingle or some other structural break command before asking Stata for r(breakdate); see here for more. After that you could do something like this, assuming that your panels are identified by countrynum.
* EX DATA
webuse usmacro, clear
tempfile append
save `append', replace
append using `append', gen(countrynum)
* Run By program (ssc install runby)
capture program drop panel_breakdate
program panel_breakdate
tsset date
regress fedfunds L.fedfunds
estat sbsingle
gen breakdate = r(breakdate)
end
runby panel_breakdate, by(countrynum) verbose
* After this format your breakdate how you please.
There is a lot wrong with your code, unfortunately, although you haven't noticed various errors because they are errors of meaning, not errors of syntax.
For a start,
foreach i in countrynum {
does not trigger a loop over the distinct values of countrynum. It is a loop over one item, the variable name countrynum.
So your test becomes
if countrynum == countrynum
which is always true, and the loop is no loop, but equivalent to
by countrynum, sort: reg y x1 x2 x3
est store `r'(breakdate)
Now the next problem is that the first command runs through several regressions, but only results for the last regression (for the last country named) will remain in memory.
The error that Stata noticed is that it does not know what you mean by
`r'(breakdate)
You are, it seems, referring to a result that requires extra syntax to get
`r(breakdate)'
Positive suggestion. Using statsby is a much better idea.
General Solution
I have a solution to your problem I believe. This program needs to all be run at the same time due to the use of local variables. This worked for me on the usmacro test data where I made half the observations country 1 and the other half country 2. It should work for you as well as long as your data is tsset already.
levelsof countrynum
foreach lev in `r(levels)' {
reg y x1 x2 x3 if countrynum == `lev'
estat sbsingle
scalar break`lev' = r(breakdate)
}
scalar list
As long as you have no scalars previously made, it will return a list of all the breakdates for the countries with the syntax of (break)(countrynum) without the parentheses. Let me know if this doesn't work for you, it's difficult without any example data from you but it works in my test environment.
Example
If you want to see how this works before you run it on your dataset use the following commands at once,
clear all
webuse usmacro
gen countrynum = 01 if _n < 35
replace countrynum = 22 if countrynum == .
tsset date
levelsof countrynum
foreach lev in `r(levels)' {
reg fedfunds L.fedfunds inflation if countrynum == `lev'
estat sbsingle
scalar break`lev' = r(breakdate)
}
scalar list
which will return the following in the stata output,
. scalar list
break22 = 1980q4
break1 = 1958q1

Clarification for a loop to create interaction terms in Stata

I found the following question/answer that I think does what I would like to do: https://www.stata.com/statalist/archive/2009-09/msg00449.html
However, I am unclear what is going on in all of it, and would like to understand better. The code for the solution is as follows:
unab vars : var1-var30
local nvar : word count `vars'
forval i = 1/`nvar' {
forval j = 1/`=`i'-1' {
local x : word `i' of `vars'
local y : word `j' of `vars'
generate `x'X`y' = `x' * `y'
}
}
I do not understand what is going on in line 4 with the statement: ``=i'-1'.
The i refers to the number in the set {1,...,n}, but I do not understand what the equals or the -1 are doing. My assumption is that the -1 is somehow removing the own observation, but I am unclear. Any explanation would be appreciated.
Suppose you have local macro i that varies over a range and you want its value minus 1. You can always do this
local j = `i' - 1
and then refer to j. You can also do this on the fly:
`= `i' - 1'
Within
`= '
Stata will evaluate the expression, here
`i' - 1
and substitute the result of that expression in a command line.
You can do this with scalars too:
scalar foo = 42
and then refer to
`= foo'
However, watch out. Scalar names and variable names occupy the same namespace.
`= scalar(foo)'
disambiguates and arguably is good style in any case.

Forvalues-loop showing incorrect syntax

I want to generate variable names that depend on given variable games.
For example, if games is given as 3, the result is
game1 = list of uniformly distributed values
game2 = same, etc.
While there are multiple examples and answers on similar questions, I cannot see why my code cannot produce the results I want
Stata shows syntax error for the following loop:
set obs 1000
forvalues i = 1(1)games {
generate game`i' = runiform()
}
Is games really a variable in Stata's sense? Holding the same constant again and again is unnecessary and inefficient.
The problem is that forvalues expects to see numbers; it won't perform evaluations on the fly. But other parts of Stata will do that.
If you know you want just 3 variables then you could do just this:
clear
set obs 1000
forvalues i = 1/3 {
generate game`i' = runiform()
}
Or you could do something like this:
clear
set obs 1000
local games = 3
forvalues i = 1/`games' {
generate game`i' = runiform()
}
That does not contradict my opening paragraph. All macro evaluations are performed before any command is executed; thus forvalues sees 3, not a local macro name.
If you were really were holding a constant in a variable, then this would work:
clear
gen games = 3
set obs 1000
forvalues i = 1/`=games[1]' {
generate game`i' = runiform()
}

Display data in Stata loop

I have a loop in Stata 12 that looks at each record in a file and if it finds a flag equal to 1 it generates five imputed values. My code looks like this:
forvalues i=1/5 {
gen y3`i' = y2
gen double h`i' = (uniform()*(1-a)+a) if flag==1
replace y3`i' = 1.6*(invibeta(7.2,2.6,h`i')/(1-invibeta(7.2,2.6,h`i')))^(1/1.7) if
flag==1
}
a is defined elsewhere. I want to check the individual imputations. Thus, I need to display the imputed variable preferably only for those cases where flag=1. I also would like to display another value, s, alongside. I need help in figuring out the syntax. I've tried every combination of quotes and subscripts that I can think of, but I keep getting error messages.
One other useful modification occurs to me. Suppose I have three concatenated files on which I want to perform this routine. Let them have a variable file equal to 1, 2 or 3. I'd like to set a separate seed for each and do it in my program so I have a record. I envision something like:
forvalues j=1/3 {
set seed=12345 if file=1
set seed=56789 if file=2
set seed=98765 if file=3
insert code above
}
Will this work?
No comment is possible on code you don't show, but the word "display" may be misleading you.
list y3`i' if flag == 1
or some variation may be what you seek. Note that display is geared to showing at most one line of output at a time.
P.S. As you are William Shakespeare, know that the mug http://www.stata.com/giftshop/much-ado-mug/ was inspired by your work.
A subsidiary question asks about choosing a different seed each time around a loop. That is easy:
forval j = 1/3 {
local seed : word `j' of 12345 56789 98765
set seed `seed'
...
}
or
tokenize 12345 56789 98765
forval j = 1/3 {
set seed ``j''
...
}

Resources