Notice: On April 23, 2014, Statalist moved from an email list to a forum, based at statalist.org.
From | Nick Cox <njcoxstata@gmail.com> |
To | statalist@hsphsun2.harvard.edu |
Subject | Re: st: Looping across observations (forwards and backwards) |
Date | Tue, 4 Oct 2011 19:53:15 +0100 |
I have looked at this again. I am still not sure what you are trying to do here, but this reproduces your first example: clear all input v_269 v_270 v_271 desired_sinalt 0 1.4 100 . 1 1.5 100 . 0 1.5 95 . 0 1.4 100 . 2 1.5 100 1 1 1.7 98 . 0 1.2 99 . 2 1.5 95 -1 0 1.8 101 . end gen long order = _n gen start = v_269 == 2 gen block = sum(start) bysort block (order) : /// gen match = sum(v_270 == v_270[1] | v_271 == v_271[1]) by block : /// replace match = sum(cond(inlist(v_269, 1, 0), v_269 * (match == 1),.)) by block : replace match = match[_N] by block : gen sinalt = cond(match == 1, 1, cond(match == 0, -1, .)) if block On Tue, Oct 4, 2011 at 3:32 PM, Nick Cox <n.j.cox@durham.ac.uk> wrote: > I don't fully understand what you are trying to do here, but > > local ++j > > need not stop before > > v_270[`j']==v_270[`i'] | v_271[`j']==v_271[`i'] > > and perhaps that is not guaranteed for all values of 2. > > so perhaps you need another condition to stop it, say that the next value of v_269 is 2. > > I think you need another approach. Evidently blocks start with some key values and then you count something within blocks. A few fragmentary suggestions > > gen start = v269 == 2 > gen block = sum(start) > egen start_v269 = total(start * v269), by(block) > egen start_v270 = total(start * v270), by(block) > egen start_v271 = total(start * v271), by(block) > > > > Nick > n.j.cox@durham.ac.uk > > -----Original Message----- > From: owner-statalist@hsphsun2.harvard.edu [mailto:owner-statalist@hsphsun2.harvard.edu] On Behalf Of Pedro Nakashima > Sent: 03 October 2011 20:39 > To: statalist@hsphsun2.harvard.edu > Subject: Re: st: Looping across observations (forwards and backwards) > > Thanks, Nick > > When I applied you tip to the code: > > clear all > input v_269 v_270 v_271 desired_sinalt > 0 1.4 100 . > 1 1.5 100 . > 0 1.5 95 . > 0 1.4 100 . > 2 1.5 100 1 > 1 1.7 98 . > 0 1.2 99 . > 2 1.5 95 -1 > 0 1.8 101 . > end > gen order = _n > gen neworder=-_n > sort neworder > gen sinalt=. > set trace on > forvalues i=1/`=_N' { > if v_269[`i']==2{ > local j=`i'+1 > while (v_270[`j']!=v_270[`i'] | v_271[`j']!=v_271[`i']) { > local ++j > } > if v_270[`j']==v_270[`i'] | v_271[`j']==v_271[`i'] { > if v_269[`j']==1{ > local sinal=1 > } > else if v_269[`j']==0 { > local sinal=-1 > } > else { > local sinal=. > } > } > replace sinalt=`sinal' in `i' > } > } > set trace off > sort order > > ,, it worked, > > But if I replace the third observation as follows: > replace v_269 = 2 in 3 > replace v_271 = 100 in 3 > > The looping never ends.. > > Also, It's important to say that if the criterion matches v_269 and > v_271 in observation number 3 (where v_269==2), as in the above > example, I want to ignore it. > > Thanks in advance for the help. > > Best regards > Pedro Nakashima. > > 2011/9/24 Nick Cox <njcoxstata@gmail.com>: >> A different comment is that it is much easier to go forwards in Stata >> than backwards. So, reversing the whole dataset, and defining spells >> "started" in a certain way might be easier. When all is done you >> reverse it again. >> >> Reversing is easy >> >> gen neworder = -_n >> sort neworder >> >> On Sat, Sep 24, 2011 at 4:07 PM, Nick Cox <njcoxstata@gmail.com> wrote: >>> When your program gets to >>> >>> replace sinalt=`sinal' in `i' >>> >>> evidently `sinal' is undefined so Stata sees >>> >>> replace sinalt= in `i' >>> >>> It tries first to interpret -in- as the name of a variable or scalar, >>> fails, and aborts with error. >>> >>> Perhaps when you coded >>> >>> if cod[j]==1 { >>> >>> you meant >>> >>> if cod[`j']==1 { >>> >>> On Sat, Sep 24, 2011 at 3:28 PM, pedromfn <nakashimapedro@gmail.com> wrote: >>> >>>> My database looks like: >>>> >>>> obs cod pr qt sinalt >>>> 1 1 1.4 100 . >>>> 2 2 1.5 100 . >>>> 3 1 1.5 95 . >>>> 4 1 1.4 100 . >>>> 5 3 1.5 100 . >>>> >>>> and I want to replace observations of sinalt in which cod==3, according to >>>> the following rule: >>>> 1) Go across observations looking for observations in which cod=3 >>>> 2) In the above example, the first observation is observation 5, in which >>>> pr[5]=1.5 and qt[5]=100. Once that observation was found, go backwards >>>> through observations looking for the first observation j in which >>>> pr[j]==pr[5] & qt[j]==qt[5]. In the example, j=2. >>>> 3) Replace sinalt[5]=`sinal' , where the macro sinal is defined as: >>>> if cod[j]==1, store in the local sinal the value 1 >>>> if cod[j]==2, store in the local sinal the value -1 >>>> 4) Once last replace was done, look for the next observation in which cod==3 >>>> and do the same thing. >>>> >>>> I wrote the following do-file, but it didn't work: >>>> >>>> forvalues i=1/`=_N' { >>>> if cod[`i']==3{ >>>> local j=`i'-1 >>>> if pr[`j']==pr[`i'] & qt[`j']==qt[`i'] { >>>> if cod[j]==1 { >>>> local sinal 1 >>>> } >>>> else if cod[`j']==2 { >>>> local sinal -1 >>>> } >>>> else { >>>> local sinal >>>> } >>>> } >>>> else { >>>> while pr[`j']!=pr[`i'] | qt[`j']!=qt[`i'] { >>>> local --j >>>> } >>>> } >>>> replace sinalt=`sinal' in `i' >>>> } >>>> } >>>> >>>> ERROR: >>>> in not found >>>> r(111); >>> >> > > * > * For searches and help try: > * http://www.stata.com/help.cgi?search > * http://www.stata.com/support/statalist/faq > * http://www.ats.ucla.edu/stat/stata/ > * * For searches and help try: * http://www.stata.com/help.cgi?search * http://www.stata.com/support/statalist/faq * http://www.ats.ucla.edu/stat/stata/