[Date Prev][Date Next][Thread Prev][Thread Next][Date index][Thread index]

From |
"Jun Xu" <mystata@hotmail.com> |

To |
statalist@hsphsun2.harvard.edu |

Subject |
Re: st: RE: RE: loop [ignore previous one (from this message), sorry!!!] |

Date |
Mon, 17 Feb 2003 18:45:11 -0600 |

Nick,

Thank you so much. After I made that change "gen long `pat02'=." it worked. Also thank you for your hints/program. Probably I shouldn't ve posted this question. Rather I better to take a course in programming. But if you have the answer at hand, would you be able to give me some general rules/if possible, some tricks for this problem to be more efficient? This program now works pretty fine with less than like 12 variables. Everything works fine except a bit slow (10 and less variables kind of fast enough). But when I play around with it using like 15 variables, it just takes forever to produce the results (like 10 minutes). I think it's probably related to the forval command in the middle part of this program. But I couldn't find a better way. Or, if I want program an ado file to do what I want (exhaust combinations), slowness should be expected. Thanks again. By the way, you're amazing!!! Some parts of the following program is wrapped-up and actually should be in one line due to the hotmail set up that I have. Not sure how it is displayed in the statalist

Jun Xu

Department of Sociology

Indiana University at Bloomington

***********************************************************************

*! version beta 0.0.1 02/15/2003

capture program drop permlist

program define permlist, rclass

version 7

preserve

tempvar pat02 pat10 varpat patfrq count miscnt hasmis

syntax varlist [,PATCORrelate(numlist) PATMIS(numlist) PATRESP SAVE(string)]

tokenize `varlist'

local nvars : word count `varlist'

while "`1'"!="" {

forval i=1/`nvars'{

local curvar`i': word `i' of `varlist'

*di "`curvar`i''"

}

macro shift

}

local imax=2^`nvars'-1

*di `imax'

*di `nvars'

/*

if _n<`imax' {

local org_n=_n

set obs `imax'

}

*/

quietly gen long `pat02'=.

quietly gen `pat10'=.

quietly gen `patfrq'=.

quietly gen str50 `varpat'=""

quietly gen `miscnt'=.

forval i = 1 / `imax' {

local addon ""

qui inbase 2 `i'

*=>di %0`nvars'.0f `r(base)' here is to display

* `r(base)' with its full length. For example

* for 1 if we want to have five digit number (should

* be equal to number of variables in this case

* 1 will be displayed as 00001

local which : di %0`nvars'.0f `r(base)'

*di "`which'"

forval j = 1 / `nvars' {

*=>substr(s,n1,n2) returns the substring of s

* starting at n1 for a length of n2

local char = substr("`which'",`j',1)

if "`char'"=="0"{

local addon "`addon'"

if "`j'"=="1"{

local ifqlf "`curvar`j''==0"

}

if "`j'">"1"{

local ifqlf "`ifqlf' & `curvar`j''==0"

}

}

if "`char'"=="1" {

local addon "`addon' `curvar`j''"

if "`j'"=="1"{

local ifqlf "`curvar`j''==1"

}

if "`j'">"1"{

local ifqlf "`ifqlf' & `curvar`j''==1"

}

}

}

quietly replace `pat02' =`which' if _n==`i'

quietly replace `pat10' =`i' if _n==`i'

quietly replace `varpat' ="`addon'" if _n==`i'

format `pat02' %0`nvars'.0f `r(base)'

quietly {

gen `count'=(`ifqlf')

sum `count', d

replace `patfrq'=`r(sum)' if _n==`i'

}

drop `count'

mark `hasmis'

markout `hasmis' `addon'

quietly sum `hasmis', d

local cntmis=`r(sum)'

quietly replace `miscnt'=`cntmis' if _n==`i'

quietly drop `hasmis'

}

*di "`addon'"

label var `pat02' pat02

label var `patfrq' patfrq

label var `miscnt' nomiscnt

if "`patresp'"~=""{

di _n(1) in g "Response Pattern of Binary(0/1) Indicators:"

tabdisp `pat02' if `pat02'~=., cell(`patfrq')

di _n(1) _skip(2) in g " pat02 = binary codes of in/out in varlist "

di _skip(2) in g " patfrq = obs counts of a response pattern."

}

di _n(2)

if "`patcorrelate'"=="0" {

forval n=1 / `imax'{

local a=`varpat'[`n']

corr `a'

}

}

if "`patcorrelate'"~="" & "`patcorrelate'"~="0" {

qui inten 2 `patcorrelate'

local a=r(ten)

local b=`varpat'[`a']

corr `b'

}

if "`patmis'"~=""{

di _n(1) in g "Counts of Nonmissing Cases in a Varlist:"

tabdisp `pat02' if `pat02'~=., cell(`miscnt')

di _n(1) _skip(2) in g " pat02 = binary codes of in/out in varlist "

di _skip(2) in g "nomiscnt = counts of nonmissing cases."

qui inten 2 `patmis'

local c=r(ten)

local d=`varpat'[`c']

local e=`miscnt'[`c']

di _n(3) in y "The nonmissing sample size for only `d' is `e'"

quietly sort `miscnt'

di _n(2)

di in g "pat02 / varpat / miscnt: top 10 or less nonmissing varlist"

di _n(1)

if `imax'<=10 {

list `pat02' `varpat' `miscnt' in 1/`imax', noobs noheader

}

else {

list `pat02' `varpat' `miscnt' in 1/10, noobs noheader

}

local lowb=`imax'-10

di _n(2)

di in g "pat02 / varpat / miscnt: bottom 10 or less nonmissing varlist"

di _n(1)

if `lowb'<=0 {

list `pat02' `varpat' `miscnt' in 1/`imax', noobs noheader

}

else {

list `pat02' `varpat' `miscnt' in `lowb'/`imax', noobs noheader

}

}

if "`save'"~=""{

preserve

drop if _n>`imax'

rename `pat02' _patbin_

rename `varpat' _varpat_

rename `miscnt' _miscnt_

rename `patfrq' _patfrq_

keep _patbin_ _varpat_ _miscnt_ _patfrq_

quietly gen str50 _varlist_="`varlist'"

save "`save'", replace

restore

}

return local varlist `"`varlist'"'

end

exit

clear

set more off

for num 1/6: set obs 100\ gen xX=invnorm(uniform()) \ gen DxX=xX>0.6

aorder

egen all = concat(Dx1-Dx6)

tab all

rename Dx1 m1

rename Dx2 y3

rename Dx5 z4

recode Dx3 1=. if _n>80

recode z4 0=. if _n>60 & _n<80

permlist Dx3 y3 Dx4 z4 Dx6 m1, patmis(001111) save(H:\my)

********************************************************************

From: "Nick Cox" <n.j.cox@durham.ac.uk>

Reply-To: statalist@hsphsun2.harvard.edu

To: <statalist@hsphsun2.harvard.edu>

Subject: st: RE: RE: loop [ignore previous one (from this message), sorry!!!]

Date: Sun, 16 Feb 2003 17:42:27 -0000

Jun Xu wrote

> This email might be kind of long, but to explain this

> problem clearly, could

> you bear with me for a second :( Thanks a lot.

>

> Thanks a lot for your help, and I have managed to write an

> ado file that

> seems to work fine till I found out that it won't work with

> a varlist of

> more than 8. I have attached our previous Q&A emails at the end.

>

> Notes:

>

> `imax': here is a macro that I have grabbed using 2^`nvars'-1.

> `nvars': is a macro containing number of variables in the varlist.

>

> part of the ado file that's relevant to my question

> ************************************************************

> ************

> ......

> ......

> ......

> *create this response pattern variabl and replace the value

> in future

> quietly gen `pat02'=.

> format `pat02' %0`nvars'.0f

>

> *create other tempvars

>

> forval i = 1 / `imax' {

> qui inbase 2 `i'

>

>

> local which : di %0`nvars'.0f `r(base)'

>

> *local a="`which'"

> *di "`which'"

>

> forval j = 1 / `nvars' {

> local char = substr("`which'",`j',1)

>

> *I only invoke `which' once within this loop

> .......

> .......

> .......

>

> }

>

>

> quietly replace `pat02'=`which' if _n==`i'

>

> *I don't see what's wrong here and I have used the

> following three *lines

> kind of check the instantaneous value of `which' and it is

> a *binary code

> everytime, but `pat02'[`i'] becomes not binary after the

> *binary code

> 100000000, so I strongly suspect either I misused the

> *replace statement, or

> there is something unique to "local which : di

> %*0`nvars'.0f `r(base)'" the

> command that Nick taught me in his email to *my question,

> which I might not

> understand well. The puzzle here is *that no problems with

> 8 variables and

> less, but not 9 variables and *above as you will see in the

> output, where

> the binary codes will have *other values than 0 and 1.

In your code `pat02' is created as a -float-. That

is, you didn't specify a variable type, so Stata created `pat02'

as a -float- (unless, as seems unlikely, you earlier -set type

double-).

There aren't enough bits in a float value to ensure that your

larger "binary" numbers are held absolutely exactly, which you

need for this problem.

The heart of the difficulty is shown by this example:

. set obs 1

. gen myvar = 11111111

. d myvar

storage display value

variable name type format label variable label

----------------------------------------------------------------------

---------

myvar float %9.0g

. format myvar %9.0f

. l

+----------+

| myvar |

|----------|

1. | 11111111 |

+----------+

. replace myvar = 111111111

(1 real change made)

. l

+-----------+

| myvar |

|-----------|

1. | 111111112 |

+-----------+

That is, despite your -format- some inaccuracy is creeping

once you have figures about as big as 10^9. (Of course,

Stata does not know that you are privately thinking of these

decimals as binary numbers.)

I think you would be better off using a -long- or

a -string- representation.

Here is some code which I think is close to what

you want.

*! NJC 16 February 2003

program countnonmissing

version 7

syntax varlist

tokenize `varlist'

local nvars : word count `varlist'

local imax = 2^`nvars' - 1

qui {

forval i = `imax'(-1)1 {

inbase 2 `i'

local which : di %0`nvars'.0f `r(base)'

noi di "{txt}`which' " _c

local vars

forval j = 1 / `nvars' {

local char = substr("`which'",`j',1)

if `char' {

local vars "`vars'``j'' "

}

}

local nv : word count `vars'

local nvm1 = `nv' - 1

local W

forval j = 1 / `nvm1' {

local wj : word `j' of `vars'

local W "`W'`wj',"

}

local wj : word `nv' of `vars'

local W "`W'`wj'"

count if !missing(`W')

noi di %6.0f r(N)

}

}

end

e.g.

countnonmissing *

countnonmissing make mpg rep78

Nick

n.j.cox@durham.ac.uk

*

* For searches and help try:

* http://www.stata.com/support/faqs/res/findit.html

* http://www.stata.com/support/statalist/faq

* http://www.ats.ucla.edu/stat/stata/

_________________________________________________________________

Protect your PC - get McAfee.com VirusScan Online http://clinic.mcafee.com/clinic/ibuy/campaign.asp?cid=3963

*

* For searches and help try:

* http://www.stata.com/support/faqs/res/findit.html

* http://www.stata.com/support/statalist/faq

* http://www.ats.ucla.edu/stat/stata/

**Follow-Ups**:**RE: st: RE: RE: loop [ignore previous one (from this message), sorry!!!]***From:*"Nick Cox" <n.j.cox@durham.ac.uk>

- Prev by Date:
**st: Levin-Lin-Chu unit root test for panel data** - Next by Date:
**st: dep. var. with zeros and fixed effect (or cluster) estimation [trim. least squares?]** - Previous by thread:
**st: Re: line_options** - Next by thread:
**RE: st: RE: RE: loop [ignore previous one (from this message), sorry!!!]** - Index(es):

© Copyright 1996–2018 StataCorp LLC | Terms of use | Privacy | Contact us | What's new | Site index |