# [R] seq_len and loops

Göran Broström goran.brostrom at umu.se
Thu Jan 2 19:00:03 CET 2014

```On 01/01/2014 07:36 PM, William Dunlap wrote:
>> 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.

Thanks Bill; I am aware of these details since my days as a successful
Fortran programmer;)! I guess this background is what makes me worry
about the apparently careless choice of variable type that I can get
away with in  R.

>
> 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.

I get your point; I however never have an 'else' part in this context
(if x == 1 I'm already done).

Another observation: The 'while (x < n) x <- x + 1' approach is very
slow compared to a for loop.

Göran Broström

> 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