[R] scoping rules for 'for' [was - Re: for/if loop ]

Duncan Murdoch murdoch at stats.uwo.ca
Thu Jan 29 16:54:17 CET 2009


On 1/29/2009 10:39 AM, davidr at rhotrading.com wrote:
> I apologize for posting a wrong opinion; I should of course have checked
> before posting.
> 
> Henrik's examples illustrate something I had never realized before, and
> it really surprised me!
> Where can I read the technical details of this scoping aspect of 'for'
> as it still presents
> some subtle puzzles for me. For example:
>> for (ii in 1:3) { print(ii); if(ii==1){ii <- 20}; print(ii); print(ii
> <- ii + 1); print(ii)}
> [1] 1
> [1] 20
> [1] 21
> [1] 21
> [1] 2
> [1] 2
> [1] 3
> [1] 3
> [1] 3
> [1] 3
> [1] 4
> [1] 4
> Why does R treat ii differently after the 'if' in the first and
> subsequent iterations?

I don't see that it does.  First time through, it prints 1, 20, 21, 21. 
  Second time through (without ii==1 being true), it prints 2, 2, 3, 3.
Third time through it prints 3,3,4,4.  What's different?


> And if the loop variable does not exist before the 'for', why is it
> created in the parent(?) environment at all?

It's created in the current evaluation frame, because that's where 
everything gets created unless you work hard to have it created 
somewhere else.

> (I.e, if ii did not exist before the for loop, it does and has value 5
> after. Wouldn't strict
> scoping mean that ii exists only within the for loop?)

R doesn't have scoping as strict as that.  For loops don't create their 
own evaluation frames.  If they did, you could not do something like this:

  x <- 0
  for (i in 1:10) {
   x <- x + i
  }

as a slow way to do sum(1:10), because the assignment within the loop 
would take place in a local evaluation frame, and be lost afterwards.

> I generally don't try to change the loop variable's value inside a loop,
> but coming from C
> or other languages, it seems natural to do so in certain circumstances.

R is not C.  Feel free to do what you like to the variable within the 
loop (though you might cause Luke to grind his teeth when it messes up 
his compiler).  It will be set to the next value in the 1:10 vector the 
next time it comes back to the top.

> And the examples are
> certainly bad programming style. But I remain confused. I assume that
> 'while' loops have different scoping
> rules?

No, the scoping rules in R are quite simple and consistent.  for and 
while have the same rules.

Duncan Murdoch

> 
> Thanks,
> 
> -- David
> 
> 
> -----Original Message-----
> From: henrik.bengtsson at gmail.com [mailto:henrik.bengtsson at gmail.com] On
> Behalf Of Henrik Bengtsson
> Sent: Wednesday, January 28, 2009 5:08 PM
> To: David Reiner <davidr at rhotrading.com>
> Cc: SnowManPaddington; r-help at r-project.org
> Subject: Re: [R] - Re: for/if loop
> 
> On Wed, Jan 28, 2009 at 2:41 PM,  <davidr at rhotrading.com> wrote:
>> Well, maybe you are just bad at typing then ;-)
>>
>> The lines rr==ii, pp==pp+1, etc. are not setting rr and pp but
> comparing
>> them.
>> Probably you want rr <- ii and pp <- pp+1, etc.
>> And the last line of your loop 'ii=ii+1' means that,
>> since the for statement is already incrementing ii,
>> you are incrementing it twice and skipping the even indices. Omit this
>> line probably.
> 
> That is actually not the case (because of the scoping rules for for(),
> I think).  Example:
> 
>> for (ii in 1:5) { print(ii); ii <- ii + 1; }
> [1] 1
> [1] 2
> [1] 3
> [1] 4
> [1] 5
> 
> Another "counter intuitive" (though it isn't) example:
> 
> for (ii in 1:3) {
>   cat("Outer ii:",ii,"\n");
>   for (ii in ii:3) {
>     cat("  Inner ii:",ii,"\n");
>   }
> }
> 
> Outer ii: 1
>   Inner ii: 1
>   Inner ii: 2
>   Inner ii: 3
> Outer ii: 2
>   Inner ii: 2
>   Inner ii: 3
> Outer ii: 3
>   Inner ii: 3
> 
> My $.02
> 
> /Henrik
> 
>> You are also forgetting(?) the operator precedence in
>> sum(lselb1[rr:ii-1]) and similar lines.
>> Note that this is equivalent to sum(lselb1[(rr-1):(ii-1)]); is that
> what
>> you meant?
>> Or did you want sum(lselb1[rr:(ii-1)])?
>> You are changing some variables but not asking R to print anything as
>> far as I can see.
>> To see the results, ask R to print hll.
>>
>> HTH,
>> -- David
>>
>> -----Original Message-----
>> From: r-help-bounces at r-project.org
> [mailto:r-help-bounces at r-project.org]
>> On Behalf Of SnowManPaddington
>> Sent: Wednesday, January 28, 2009 3:59 PM
>> To: r-help at r-project.org
>> Subject: - Re: [R] for/if loop
>>
>>
>> Hi ya, I've revised the code (and finally know what I m doing.. :-D)
>>
>> The good news is.. I dont get any error message, but the bad news is
> the
>> following optim generate no results. I still think there is something
> to
>> do
>> with my loop... can anyone advice? Thanks again!!!
>>
>>
>>
>> pp=1
>> rr=1
>>
>> for (ii in 1:n){
>>        if (!(panel[ii] == pp)){
>>                hll[pp,1] == sum(lselb1[rr:ii-1])
>>                hll[pp,2] == sum(lselb2[rr:ii-1])
>>                rr==ii
>>                pp==pp+1
>>                }
>>
>>        if (ii==n){
>>                hll[pp,1] == sum(lselb1[rr:ii])
>>                hll[pp,2] == sum(lselb2[rr:ii])
>>                rr==ii
>>                pp==pp+1
>>                }
>>        ii=ii+1
>> }
>>
>>
>>
>>
>>
>> pp=1
>> rr=1
>>
>> for (ii in 1:n){
>>        if (!(panel[ii] == pp)){
>>                hll[pp,1] == sum(lselb1[rr:ii-1])
>>                hll[pp,2] == sum(lselb2[rr:ii-1])
>>                rr==ii
>>                pp==pp+1
>>                }
>>
>>        if (ii==n){
>>                hll[pp,1] == sum(lselb1[rr:ii])
>>                hll[pp,2] == sum(lselb2[rr:ii])
>>                rr==ii
>>                pp==pp+1
>>                }
>>        ii=ii+1
>> }
>>
>>
>>
>>
>>
>> SnowManPaddington wrote:
>>>
>>> Hi, it's my first time to write a loop with R for my homework. This
>> loop
>>> is part of the function. I wanna assign values for hll according to
>> panel
>>> [ii,1]=pp. I didn't get any error message in this part. but then when
>> I
>>> further calculate another stuff with hll, the function can't return.
> I
>>> think it must be some problem in my loop. Probably something stupid
> or
>>> easy. But I tried to look for previous posts in forum and read R
>> language
>>> help. But none can help.. Thanks!
>>>
>>>
>>>
>>> for (ii in 1:100){
>>>       for (pp in 1:pp+1){
>>>               for (rr in 1:rr+1){
>>>                       if (panel[ii,1]!=pp)
>>>                       {
>>>                       hll(pp,1)=ColSums(lselb1(rr:ii-1,1))
>>>                       hll(pp,2)=ColSums(lselb2(rr:ii-1,1))
>>>                       rr=ii
>>>                       pp=pp+1
>>>                       }
>>>                       else
>>>                       {
>>>                       hll(pp,1)=ColSums(lselb1(rr:ii,1))
>>>                       hll(pp,2)=ColSums(lselb2(rr:ii,1))
>>>                       rr=ii
>>>                       pp=pp+1}
>>>                       }
>>>                       }}}
>>>
>>>
>>> in fact I have the corresponding Gauss code here. But I really don't
>> know
>>> how to write such loop in R.
>>>
>>> rr=1;
>>> ii=1;
>>> pp=1;
>>> do until ii==n+1;
>>>       if pan[ii,1] ne pp;
>>>               hll[pp,1]=sumc(lselb1[rr:ii-1,1]);
>>>               hll[pp,2]=sumc(lselb2[rr:ii-1,1]);
>>>               rr=ii;
>>>               pp=pp+1;
>>>       endif;
>>>       if ii==n;
>>>               hll[pp,1]=sumc(lselb1[rr:ii,1]);
>>>               hll[pp,2]=sumc(lselb2[rr:ii,1]);
>>>               rr=ii;
>>>               pp=pp+1;
>>>       endif;
>>>       ii=ii+1;
>>> endo;
>>>
>>>
>>
>> --
>> View this message in context:
>> http://www.nabble.com/for-if-loop-tp21701496p21715928.html
>> Sent from the R help mailing list archive at Nabble.com.
>>
> 
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.




More information about the R-help mailing list