invalid syntax and program error - stata

forvalue n=1/18 {
if f_3_`n'_==1 {
local i= `0'
local y=`i'+1
gen ownagri_`y' = f123a_`y'_
replace ownagri_`y' = . if f_2_sel_`n' ==1
local i = `i'+1
}
else if f_3_`n'_==2 {
local i= `0'
local y=`i'+1
gen agri_`y' = f126_a1_`n'_
replace agri_`y' = .if f_2_sel_`n' ==1
local i = `i'+1
}
else if f_3_`n'_==3 {
local i= `0'
local y=`i'+1
gen nonagri_`y' = f126_a1_`n'_
replace nonagri_`y' = . if f_2_sel_`n' ==1
local i = `i'+1
}
else if f_3_`n'_==4 {
local i=`0'
local y=`i'+1 {
gen nonagriself_`y' = f128_`n'_
replace nonagriself_`y' = . if f_2_sel_`n' ==1
local i = `i'+1
}
else if f_3_`n'_==5 {
local i=`0'
local y=`i'+1
gen military_`y' = . if f_2_sel_`n' ==1
local i = `i'+1
}}
}
Stata says my command contains invalid syntax and there is program error: code follows on the same line as close brace.
EDIT:
forvalue n = 1/18 {
if f_3_`n'_==1 {
local y1 = 1
gen ownagri_`y1' = f123a_`y1'_
replace ownagri_`y' = . if f_2_sel_`n'_ ==1
local y1 = `y1'+1
}
else if f_3_`n'_==2 {
local y2 = 1
gen agri_`y2' = f126_a1_`y2'_
replace agri_`y2' = . if f_2_sel_`n'_ ==1
local y2 = `y2'+1
}
else if f_3_`n'_==3 {
local y3 = 1
gen nonagri_`y3' = f126_a1_`y3'_
replace nonagri_`y3' = . if f_2_sel_`n'_ ==1
local y3 = `y3'+1
}
else if f_3_`n'_==4 {
local y4 = 1
gen nonagriself_`y4' = f128_`y4'_
replace nonagriself_`y4' = . if f_2_sel_`n'_ ==1
local y4 = `y4'+1
}
else if f_3_`n'_==6 {
local y5 = 1
gen military_`y5' = f129a_`y5'_
replace military_`y5' = . if f_2_sel_`n'_ ==1 ,modify
local y5 = `y5'+1
}
}
I modified the code and the program seems to work, but the results generated seem to be incomplete. The result shows as follow:
(20,070 missing values generated)
(2,194 real changes made, 2,194 to missing)
(19,229 missing values generated)
(1,129 real changes made, 1,129 to missing)
Why?

Specific comments already made:
a. The }} on the next to last line should be } (William Lisowski)
b. Lines like
if f_3_`n'_==1
are evaluated as if
if f_3_`n'_[1] ==1
which is usually not what is wanted. See this FAQ for much more. But this is not a syntax error.
New specific comment:
c. The line
local y=`i'+1 {
has a spurious { that should be removed.
General comments:
A. Throwing a large chunk of code at us without context is poor question style. You're new to this, which is fine, but equally there is accessible advice for you to follow e.g. on good examples.
B. There is no context here on what you are trying to do and no data example. The Statalist advice on how to present data examples in its FAQ carries over to other sites with easy small modifications (e.g. the advice there on delimiters [CODE] and {/CODE] is irrelevant here).
C. There is repeated code in every branch which can be moved, producing this:
local i = `0'
local y = `i'+1
forvalue n = 1/18 {
if f_3_`n'_==1 {
gen ownagri_`y' = f123a_`y'_
replace ownagri_`y' = . if f_2_sel_`n' ==1
}
else if f_3_`n'_==2 {
gen agri_`y' = f126_a1_`n'_
replace agri_`y' = .if f_2_sel_`n' ==1
}
else if f_3_`n'_==3 {
gen nonagri_`y' = f126_a1_`n'_
replace nonagri_`y' = . if f_2_sel_`n' ==1
}
else if f_3_`n'_==4 {
gen nonagriself_`y' = f128_`n'_
replace nonagriself_`y' = . if f_2_sel_`n' ==1
}
else if f_3_`n'_==5 {
gen military_`y' = . if f_2_sel_`n' ==1
}
}
local i = `i'+1
Whether this code is what you want we cannot say, but it looks legal, and it's shorter than your original.

Related

Modify allpossible stata ado file , so it accepts any number of variables

I am trying to use allpossible.ado to examine the interactions between several variables. It does not accept more than 6 variables. is there a way to modify the code so it accepts any number of variables.
This is the code, This module was written by Nicholas J. Cox
program define allpossible
version 7.0
* process syntax
gettoken cmd 0 : 0
syntax varlist(min=2 numeric ts) [aw fw iw pw] [if] [in] , /*
*/ [ ECLASS(str) RCLASS(str) NPMAX(int -1) * Format(str) /*
*/ CELLWidth(int 12) Detail ]
marksample touse
qui count if `touse'
if r(N) == 0 {
error 2000
}
if "`eclass'`rclass'" == "" {
di as err "must specify at least one of eclass() or rclass()"
exit 198
}
if "`rclass'" != "" {
local nr : word count `rclass'
if `nr' < 2 {
di as err "rclass() invalid"
exit 198
}
tokenize `rclass'
local rprog "qui `1'"
mac shift
local rclass `*'
}
tokenize `varlist'
local response `1'
macro shift
local rest `*'
local np : word count `rest'
local npmax = cond(`npmax' > 0 , min(`npmax',`np', 6), `np')
local nfits = 0
forval i = 0 / `npmax' {
local nfits = `nfits' + comb(`np',`i')
}
qui count
if r(N) < `nfits' {
di as err "sorry: # of observations should be at least `nfits'"
exit 198
}
* wire in response and apply any weights
local cmd "`cmd' `response'"
if "`detail'" != "" {
local cmd "noisily `cmd'"
}
local etc "[`weight' `exp'] if `touse', `options'"
* main loop, except that we break out somewhere before repetition
qui while 1 {
* no predictors
`cmd' `etc'
foreach s of local eclass {
tempvar v`s'
gen double `v`s'' = e(`s') in 1
label var `v`s'' "`s'"
local results "`results'`v`s'' "
}
if "`rclass'" != "" {
`rprog'
foreach s of local rclass {
tempvar v`s'
gen double `v`s'' = r(`s') in 1
label var `v`s'' "`s'"
local results "`results'`v`s'' "
}
}
tempvar predictors model
gen str6 `predictors' = "(none)" in 1
label var `predictors' "predictors"
gen byte `model' = _n
label var `model' "model"
* one predictor
local p = 1
qui forval i = 1 / `np' {
`cmd' ``i'' `etc'
local p = `p' + 1
foreach s of local eclass {
replace `v`s'' = e(`s') in `p'
}
if "`rclass'" != "" {
`rprog'
foreach s of local rclass {
replace `v`s'' = r(`s') in `p'
}
}
replace `predictors' = "`i'" in `p'
}
if `npmax' == 1 {
continue, break
}
* two predictors
local npm1 = `np' - 1
qui forval i = 1 / `npm1' {
local j1 = `i' + 1
forval j = `j1' / `np' {
local p = `p' + 1
`cmd' ``i'' ``j'' `etc'
foreach s of local eclass {
replace `v`s'' = e(`s') in `p'
}
if "`rclass'" != "" {
`rprog'
foreach s of local rclass {
replace `v`s'' = r(`s') in `p'
}
}
replace `predictors' = "`i' `j'" in `p'
}
}
if `npmax' == 2 {
continue, break
}
* three predictors
local npm2 = `np' - 2
qui forval i = 1 / `npm2' {
local j1 = `i' + 1
forval j = `j1' / `npm1' {
local k1 = `j' + 1
forval k = `k1' / `np' {
local p = `p' + 1
`cmd' ``i'' ``j'' ``k'' `etc'
foreach s of local eclass {
replace `v`s'' = e(`s') in `p'
}
if "`rclass'" != "" {
`rprog'
foreach s of local rclass {
replace `v`s'' = r(`s') in `p'
}
}
replace `predictors' = "`i' `j' `k'" in `p'
}
}
}
if `npmax' == 3 {
continue, break
}
* four predictors
local npm3 = `np' - 3
qui forval i = 1 / `npm3' {
local j1 = `i' + 1
forval j = `j1' / `npm2' {
local k1 = `j' + 1
forval k = `k1' / `npm1' {
local l1 = `k' + 1
forval l = `l1' / `np' {
local p = `p' + 1
`cmd' ``i'' ``j'' ``k'' ``l'' `etc'
foreach s of local eclass {
replace `v`s'' = e(`s') in `p'
}
if "`rclass'" != "" {
`rprog'
foreach s of local rclass {
replace `v`s'' = r(`s') in `p'
}
}
replace `predictors' = "`i' `j' `k' `l'" in `p'
}
}
}
}
if `npmax' == 4 {
continue, break
}
* five predictors
local npm4 = `np' - 4
qui forval i = 1 / `npm4' {
local j1 = `i' + 1
forval j = `j1' / `npm3' {
local k1 = `j' + 1
forval k = `k1' / `npm2' {
local l1 = `k' + 1
forval l = `l1' / `npm1' {
local m1 = `l' + 1
forval m = `m1' / `np' {
local p = `p' + 1
`cmd' ``i'' ``j'' ``k'' ``l'' ``m'' `etc'
foreach s of local eclass {
replace `v`s'' = e(`s') in `p'
}
if "`rclass'" != "" {
`rprog'
foreach s of local rclass {
replace `v`s'' = r(`s') in `p'
}
}
replace `predictors' = "`i' `j' `k' `l' `m'" in `p'
}
}
}
}
}
if `npmax' == 5 {
continue, break
}
* six predictors
local npm5 = `np' - 5
quietly forval i = 1 / `npm5' {
local j1 = `i' + 1
forval j = `j1' / `npm4' {
local k1 = `j' + 1
forval k = `k1' / `npm3' {
local l1 = `k' + 1
forval l = `l1' / `npm2' {
local m1 = `l' + 1
forval m = `m1' / `npm1' {
local n1 = `m' + 1
forval n = `n1' / `np' {
local p = `p' + 1
`cmd' ``i'' ``j'' ``k'' ``l'' ``m'' ``n'' `etc'
foreach s of local eclass {
replace `v`s'' = e(`s') in `p'
}
if "`rclass'" != "" {
`rprog'
foreach s of local rclass {
replace `v`s'' = r(`s') in `p'
}
}
replace `predictors' = "`i' `j' `k' `l' `m' `n'" in `p'
}
}
}
}
}
}
if `npmax' == 6 {
continue, break
}
} /* main loop */
* table output
* integers mapped to strings to protect against decimal places
qui foreach v of local results {
capture assert `v' == int(`v')
if _rc == 0 {
tempvar v2
gen str1 `v2' = ""
replace `v2' = string(`v', "%9.0f")
_crcslbl `v2' `v'
local Results "`Results' `v2'"
}
else local Results "`Results' `v'"
}
if "`format'" == "" {
local format "%4.3f"
}
tabdisp `model' in 1 / `p', c(`predictors' `Results') /*
*/ format(`format') cellwidth(`cellwidth')
di
forval i = 1 / `np' {
di as res " `i'" as text "{col 10}``i''"
}
end
I would like to make it able to accept any number of variable.

Looping in Mata with OLS

I need help with looping in Mata. I have to write a code for Beta coefficients for OLS in Mata using a loop. I am not sure how to call for the variables and create the code. Here is what I have so far.
foreach j of local X {
if { //for X'X
matrix XX = [mata:XX = cross(X,1 , X,1)]
XX
}
else {
mata:Xy = cross(X,1 , y,0)
Xy
}
I am getting an error message "invalid syntax".
I'm not sure what you need the loop for. Perhaps you can provide more information about that. However the following example may help you implement OLS in mata.
Load example data from bcuse:
ssc install bcuse
clear
bcuse bwght
mata
x = st_data(., ("male", "parity","lfaminc","packs"))
cons = J(rows(x), 1, 1)
X = (x, cons)
y = st_data(., ("lbwght"))
beta_hat = (invsym(X'*X))*(X'*y)
e_hat = y - X * beta_hat
s2 = (1 / (rows(X) - cols(X))) * (e_hat' * e_hat)
B = J(cols(X), cols(X), 0)
n = rows(X)
for (i=1; i<=n; i++) {
B =B+(e_hat[i,1]*X[i,.])'*(e_hat[i,1]*X[i,.])
}
V_robust = (n/(n-cols(X)))*invsym(X'*X)*B*invsym(X'*X)
se_robust = sqrt(diagonal(V_robust))
V_ols = s2 * invsym(X'*X)
se_ols = sqrt(diagonal(V_ols))
beta_hat
se_robust
end
This is far from the only way to implement OLS using mata. See the Stata Blog for another example using quadcross, I like my example because it preserves a little more of the matrix algebra in the code.

Why is this regression in Stata not progressing nor returning an error code?

I am running a multi-level logistic regression in Stata on multiple imputed data with the following command:
xi: mi estimate, cmdok post: melogit outcome i.var1 i.var2 i.var3, difficult || id:
I have succeeded in running similar models with the same covariates and different outcomes. These models only take 1 to 2 minutes using my dataset (approx. n=130,000 with n=10 imputations).
For other outcomes, even after many hours, Stata reaches a certain point and is running "something" but I'm not sure what (i.e. the circle in the bottom right is spinning). I used set trace on to check what was happening under the hood (last approx. 100 lines of output below). I'm not familiar with Mata. Stata reaches this point and seemingly doesn't progress any further, but doesn't return an error code and stop the program. Can anyone suggest why Stata is struggling to proceed any further with the regression, or suggest alternatives to avoid this problem? The same issue occurs both with melogit and meglm with a link(logit) and family(binomial).
- syntax name(name=maxmin) [, NEGH TOLerance(numlist ma
> x=1 >=0) LTOLerance(numlist max=1 >=0) NONRTOLerance NRTOLerance(numlist max=1 >=0)
> QTOLerance(numlist max=1 >=0) GTOLerance(numlist max=1 >=0) ITERate(numlist max=1
> >=0) NOTCONCAVE(numlist max=1 >=0) ndami DIFficult HALFSTEPonly DOOPT SEArch(name)
> Repeat(passthru) Bounds(string) SCore(string) noWARNing noCLEAR noLOg DOTs SHOWTOLe
> rance SHOWNRtolerance SHOWSTEP TRace COEFDIffs GRADient HESSian noSKIPline noOUTput
> Level(cilevel) moptobj(string) * ]
- if `:length local nrtolerance' {
= if 0 {
opts_exclusive "nrtolerance() `nonrtolerance'"
}
- if `:length local qtolerance' {
= if 0 {
opts_exclusive "qtolerance() `nonrtolerance'"
}
- opts_exclusive "`nonrtolerance' `shownrtolerance'"
= opts_exclusive " "
---------------------------- begin opts_exclusive ---
- version 8.2
- args opts optname errcode
- local opts `opts'
= local opts
- local n 0
- while `"`opts'"' != "" {
= while `""' != "" {
local ++n
gettoken item`n' opts : opts, bind
}
- if `n' < 2 {
= if 0 < 2 {
- exit
------------------------------ end opts_exclusive ---
- if `:length local shownrtolerance' {
= if 0 {
local showtolerance showtolerance
}
- if "$ML_preserve" != "no" {
= if "no" != "no" {
if `:length local score' {
di as err "May not specify score() option unless" _n
> " a) estimation subsample is the entire data in memory, or" _n " b) you s
> pecify nopreserve option on -ml model- statement (meaning" _n " your evalua
> tion program explicitly restricts itself to obs." _n " for which $" "ML_sam
> p==1."
exit 198
}
preserve
local N = c(N)
quietly keep if $ML_sample
if (`N' != c(N)) {
mata: Mopt_init_regetviews()
}
}
- if `:length local score' {
= if 0 {
SetupScore `"$ML_evaltype"' `"`score'"' $ML_n $ML_dim
local scores "`s(scores)'"
}
- local tropts `log' `dots' `showtolerance' `showstep'
> `trace' `coefdiffs'
= local tropts
- if "`tropts'" != "nolog" {
= if "" != "nolog" {
- local tropts `tropts' `gradient' `hessian'
= local tropts
- if "`skipline'" == "" {
= if "" == "" {
- if "`iterate'" != "0" | `:length local tropts' {
= if "" != "0" | 0 {
- di
- }
- }
- }
- else {
local gradient
local hessian
local nolog nolog
}
- if "`search'" != "off" & "`iterate'" != "0" {
= if "off" != "off" & "" != "0" {
if "`search'" == "quietly" {
local sopts nolog
}
else {
if `:length local tropts' {
if "`tropts'" != "nolog" {
local sopts trace
}
else local sopts nolog
}
}
if "`search'" == "norescale" {
local sopts `sopts' norescale
}
Search `bounds', nopreserve `sopts' `repeat' `maxmin'
}
- tempname value b V iV
- `vv' mata: Mopt_maxmin()
= version 13: mata: Mopt_maxmin()

Using egen functions with replace

I created a new variable from the mean of another variable using egen:
egen afd_lr2 = mean(afd_lire2w) if ost == 0
Now I would like to replace the values with the mean of another variable if ost == 1:
replace afd_lr2 = mean(afd_lireo) if ost ==1
This is not possible, as the mean function cannot be used with the replace command.
How can I achieve my goal?
The following works for me:
sysuse auto, clear
generate price2 = price + 5345
egen a_price = mean(price) if foreign == 0
egen b_price = mean(price2) if foreign == 1
replace a_price = b_price if foreign == 1
This should work
egen afd_lr2 = mean(cond(ost == 0, afd_lire2w, cond(ost == 1, afd_lireo, .))), by(ost)
Here is a test:
clear
input float(group y1 y2)
1 42 .
1 42 .
2 . 999
2 . 999
end
egen mean = mean(cond(group == 1, y1, cond(group == 2, y2, .))), by(group)
tabdisp group, c(mean)
----------------------
group | mean
----------+-----------
1 | 42
2 | 999
----------------------
The key is that the mean() function of egen feeds on an expression, which can be more complicated than a single variable name. That said, this is trickier than I would generally advise, as
generate work = afd_lire2w if ost == 0
replace work = afd_lireo if ost == 1
egen mean = mean(work), by(ost)
is easier to understand and should occur to a programmer any way.

Using local in a forvalues loop reports a syntax error

I am using two-level loops to create a set of variables. But Stata reports a syntax error.
forvalues i = 1/5 {
local to `i'+1
dis `to'
forvalues j = `to'/6{
dis `j'
gen e_`i'_`j' = .
}
}
I could not figure out where I made the syntax error.
And a follow-up question. I would like to change how the number of loops are coded in the example above. Right now, it's hard-coded as 5 and 6. But I want to make it based on the data. For instance,I am coding as below:
sum x
scalar x_max_1 = `r(max)'-1
scalar x_max_2 = `r(max)'
forvalues i = 1/x_max_1 {
local to = `i'+1
dis `to'
forvalues j = `to'/x_max_2{
dis `j'
gen e_`i'_`j' = .
}
}
However, Stata reports a syntax error in this case. I am not sure why. The scalar is a numeric variable. Why would the code above not work?
Your code would be better as
forvalues i = 1/5 {
local to = `i' + 1
forvalues j = `to'/6 {
gen e_`i'_`j' = .
}
}
With your code you went
local to `i' + 1
so first time around the loop to becomes the string or text 1 + 1 which is then illegal as an argument to forvalues. That is, a local definition without an = sign will result in copying of text, not evaluation of the expression.
The way you used display could not show you this error because display used that way will evaluate expressions to the extent possible. If you had insisted that the macro was a string with
di "`to'"
then you would have seen its contents.
Another way to do it is
forvalues i = 1/5 {
forvalues j = `= `i' + 1'/6 {
gen e_`i'_`j' = .
}
}
EDIT
You asked further about
sum x
scalar x_max_1 = `r(max)'-1
scalar x_max_2 = `r(max)'
forvalues i = 1/x_max_1 {
and quite a lot can be said about that. Let's work backwards from one of various better solutions:
sum x, meanonly
forvalues i = 1/`= r(max) - 1' {
or another, perhaps a little more transparent:
sum x, meanonly
local max = r(max) - 1
forvalues i = 1/`max' {
What are the messages here:
If you only want the maximum, specify meanonly. Agreed: the option name alone does not imply this. See https://www.stata-journal.com/sjpdf.html?articlenum=st0135 for more.
What is the point of pushing the r-class result r(max) into a scalar? You already have what you need in r(max). Educate yourself out of this with the following analogy.
I have what I want. Now I put it into a box. Now I take it out of the box. Now I have what I want again. Come to think of it, the box business can be cut.
The box is the scalar, two scalars in this case.
forvalues won't evaluate scalars to give you the number you want. That will happen in many languages, but not here.
More subtly, forvalues doesn't even evaluate local references or similar constructs. What happens is that Stata's generic syntax parser does that for you before what you typed is passed to forvalues.