blackmagic
blackmagic

Reputation: 21

r(109) error message Code Iterating Number in a String

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

Answers (2)

Nick Cox
Nick Cox

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

AlexK
AlexK

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

Related Questions