[R] seq_len and loops

William Dunlap wdunlap at tibco.com
Wed Jan 1 19:36:44 CET 2014


> 2. However, Bill (and Henrik)  raised the question of replacing '1' with
> '1L'; I understand the meaning of that, but does it matter (in practice)?
> On 12/22/2013 06:57 PM, William Dunlap wrote:
> >>> for (i in seq_len(x - 1) + 1)
> >>>
> >>> should be efficient and safe.
> >>
> >> Oops, not safe when x is 0.
> >
> > Also, the '+ 1' should be '+ 1L' to get the same answer as
> > seq_len(x)[-1].

It depends what your practice involves.

seq_len(n)[-1], 2:n, and seq_len(n-1)+1L all  produce an integer vector (if 0<n<2^31 or so).
seq_len(n-1)+1 produces a numeric (double precision floating point) vector.

Integers and numerics have different properties which might affect your results,
but in many cases you will not care.   Integers use 4 bytes of memory, numerics 8.
Integers have 32 bits of precision, numerics 52.  Integers range from -2^31+1 to 2^31-1
and arithmetic which would give a result outside of that range results in NA (with a warning).
Numerics range from c. -2^1023 (c. -10^308) to c. 2^1023 (c. 10^308) and arithmetic
which would give a result outside of that range results in +-Inf.

If you prefer a sequence to be numeric, then use as.numeric(seq_len(n)), as.numeric(seq_len(n))[-1],
or seq_len(n)+1 when making it.  If you prefer integers, then use seq_len(n), seq_len(n)[-1], or seq_len(n)+1L.
If you don't care, do whatever seems easiest at the time. 

> if (x > 1){
>     for (x in 2:x){
>        ...
> 
> is the easiest, most effective,  and most easy-to-understand.

The dangerous part of that idiom is what you do in the 'else' part of the 'if' statement.
Do both clauses make objects with the same names and types?  I mildly prefer avoiding
if statements because it makes reasoning about the results of the code more complicated.

Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com


> -----Original Message-----
> From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf
> Of Göran Broström
> Sent: Tuesday, December 31, 2013 4:10 PM
> To: r-help at R-project.org
> Subject: Re: [R] seq_len and loops
> 
> Thanks for the answers from Duncan, Bill, Gabor, and Henrik. You
> convinced me that
> 
> 1. The solution
> 
> if (x > 1){
>     for (x in 2:x){
>        ...
> 
> is the easiest, most effective,  and most easy-to-understand.
> 
> 2. However, Bill (and Henrik)  raised the question of replacing '1' with
> '1L'; I understand the meaning of that, but does it matter (in practice)?
> 
> 3. Noone commented upon
> 
> i <- 1
> while (i < x){
>     i <- i + 1
>     ...
> }
> 
> I suppose that it means that it is the best solution.
> 
> Thanks, and Happy New Year 2014!
> 
> Göran
> 
> On 12/22/2013 06:57 PM, William Dunlap wrote:
> >>> for (i in seq_len(x - 1) + 1)
> >>>
> >>> should be efficient and safe.
> >>
> >> Oops, not safe when x is 0.
> >
> > Also, the '+ 1' should be '+ 1L' to get the same answer as
> > seq_len(x)[-1].
> >
> > Bill Dunlap
> > Spotfire, TIBCO Software
> > wdunlap tibco.com
> >
> >
> >> -----Original Message-----
> >> From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On
> Behalf
> >> Of Duncan Murdoch
> >> Sent: Saturday, December 21, 2013 3:52 PM
> >> To: Göran Broström; R-help at r-project.org
> >> Subject: Re: [R] seq_len and loops
> >>
> >> On 13-12-21 6:50 PM, Duncan Murdoch wrote:
> >>> On 13-12-21 5:57 PM, Göran Broström wrote:
> >>>> I was recently reminded on this list that
> >>>>
> >>>> "Using 1:ncol() is bad practice (seq_len is designed for that purpose)"
> >>>> (Ripley)
> >>>>
> >>>> This triggers the following question: What is "good practice" for
> >>>> 2:ncol(x)? (This is not a joke; in a recursive situation it often makes
> >>>> sense to perform the calculation for the start value i = 1, then
> >>>> continue with a loop over the rest, "the Fortran way";)
> >>>>
> >>>> I usually use
> >>>>
> >>>> if (ncol(x) > 1)
> >>>>         for (i in 2:ncol(x)){
> >>>>            ....
> >>>>
> >>>> but I can think of
> >>>>
> >>>> for (i in seq_len(x - 1)){
> >>>>         I <- i + 1
> >>>>        ....
> >>>>
> >>>> and
> >>>>
> >>>> i <- 1
> >>>> while (i < ncol(x)){
> >>>>         i <- i + 1
> >>>>         ....
> >>>>
> >>>> What is "good practice" (efficient and safe)?
> >>>
> >>> for (i in seq_len(x - 1) + 1)
> >>>
> >>> should be efficient and safe.
> >>
> >> Oops, not safe when x is 0.
> >>
> >>   >
> >> A little less efficient, but clearer would be
> >>>
> >>> for (i in seq_len(x)[-1])
> >>>
> >>> Duncan Murdoch
> >>>
> >>
> >> ______________________________________________
> >> 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.
> 
> ______________________________________________
> 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