Reputation: 21
I have Stata code to read a bunch of .csv files. I read a variable's data (one column) then I merge
it with what I have. Then I try and get it to repeat. I know lines 3 through 10 work.
local md="0301"
while `md'<="0331" {
insheet using "Model_11.2.1_2020`md'_results.csv", clear
gen pvi_`md'=toxpiscore
keep name pvi_`md'
sort name
merge 1:1 name using pvi_scores
drop _m
sort name
save pvi_scores, replace
local md=`md'+1
}
Simplified to where I think the error is
local md="0301"
while `md'<="0331" {
local md=`md'+1
}
I get the r(109)
error. So I think the
local md = `md' + 1
is the issue. Is it a string plus a number that causes the issue?
Upvotes: 2
Views: 376
Reputation: 37208
r(109)
is type mismatch: you tried to do a string operation, but Stata sees a number or numbers, or a numeric operation but Stata sees a string or strings.
. error 109
type mismatch
r(109);
You identified the essential problem.
I would do this:
forval f = 301/331 {
local F "0`f'"
// work in terms of `f' or `F' as needed
}
or this:
forval f = 301/331 {
local F : di %04.0f `f'
// work in terms of `f' or `F' as needed
}
There is nothing wrong in using while
. But whenever the problem is reducible to looping over adjacent integers, forvalues
is cleaner and simpler. Incrementing by 1 each time round the loop is automatic.
The needed twist is thus to prepend "0"
or equivalently to push the integers through a display format with a leading zero. Then you have a local macro that is a string. Really, all local macros are strings; it's just that Stata will treat the contents -- once the macro is evaluated -- as numeric if that makes sense. You can add (concatenate) strings, as done implicitly above, or by something like
local wanted = "0" + "311"
but the key is that both operands must be string, as indicated here by quotation mark delimiters. That fact isn't specific to local macros, but applies to global macros, scalars and variables too.
The Tip here discusses the problem.
Upvotes: 1
Reputation: 3011
Not an expert on this matter, but believe you should be able to loop over numeric macro values and concatenate the values with the rest of your string inside the loop:
local mdn = 301
while `mdn' <= 331 {
* concatenate string with local macro
local md = "0" + "`mdn'"
* can also use local md "0`mdn'"
insheet using "Model_11.2.1_2020`md'_results.csv", clear
gen pvi_`md'=toxpiscore
keep name pvi_`md'
sort name
merge 1:1 name using pvi_scores
drop _m
sort name
save pvi_scores, replace
local mdn=`mdn'+1
}
Upvotes: 1