Notice: On April 23, 2014, Statalist moved from an email list to a forum, based at statalist.org.

# Re: st: Looping across observations (forwards and backwards)

 From Nick Cox 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:
>>>> 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/
```