Stata The Stata listserver
[Date Prev][Date Next][Thread Prev][Thread Next][Date index][Thread index]

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


From   "Nick Cox" <n.j.cox@durham.ac.uk>
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/



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