For loop in R starting from other value

This has been bothering me for some time now. Imagine you have to/want to use a loop.

If you write a loop, but you want to start from the number 2, you'd use the following:

for (i in 2:length(variable1) { ... }

The problem arises when you try to assign values like such:

variable2 <- 1:length(variable1)
for (i in 2:length(variable1) {
    variable2[i] <- sample(variable1, 1)  # silly example; ignore it content-wise
}

Now, no matter if you would have a smaller vector initialized, it will often be problematic with the obtained variable2, since it has a "1" in the first position. What is the easiest way to deal with a for loop when you want to start from a higher number? And is there a better way than having to use i <- i+i, since we then have to also let it run from 1 to length(variable1) minus 1. Am I missing an easy solution?

While I am at it, what is the best way to predefine a variable before a for loop? I usually use variable2 <- 1:length(variable1), when I know variable2 should be a variable with the length of variable1. Is this the fastest way to allocate memory?

EDIT: I kind of realized just now that it might be easiest to do:

variable2 <- 2:length(variable1)
for (i in 2:length(variable1) {
    variable2[i-1]
}

But I am still open for better suggestions.

Answers


Don't hardcode the beginning index.

from <- 2
to <- length(variable) 
for (i in from:to) { 
  variable2[i - from + 1] <- sample(variable1, 1)
} 

or, if you find that more expressive

offset <- 1
to <- length(variable) 
for(i in (offset + 1):to) { 
  variable2[i-offset] <- sample(variable1, 1)
}

Themel's answer works great.

More generally you can use pretty much any sequence when iterating. so we could have

names <- c("Alice", "Bob", "Eve")
for(i in names) {
  print(i)
}

or

names <- c("Alice", "Bob", "Eve")
for(i in seq_along(names)) {
  print(names[i])
}

See ?seq_along for a handy primer on that. seq_along() is nice because it is a little safer than specifying the array bounds yourself, should you want to iterate over the whole array.

You can iterate by an arbitrary sequence, e.g. for(i in c(3, 5, 12, 47)) { # do stuff }. If you get too tricky you'll trip yourself up, but bear in mind that you have that flexibility.

In this case the only thing I would change would be to avoid creating a variable for the end unless you're planning on having it be something other than the length of the vector. so:

from <- 2
for (i in from:length(variable)) { 
  variable2[i - from + 1] <- sample(variable1, 1)
} 

There are also a number of ways around looping in R, and sometimes (though not always), exploring those is valuable.


Well, the usual R idiom would probably be to use sapply and let it handle the bookkeeping of filling up the result vector. Something like this:

> sapply(2:5, function(x) {x*10})
[1] 20 30 40 50

Need Your Help

Do you use regular builds as a coding tool?

c# performance delphi compiler-construction

We have a large (about 580,000 loc) application which in Delphi 2006 builds (on my machine) in around 20 seconds. When you have build times in seconds, you tend to use the compiler as a tool. i.e. ...

debian: mysql-workbench installation error

linux python-2.7 debian mysql-python mysql-workbench

I'm trying to install mysql-workbench-gpl-5.2.45 from the source code on Linux debian 2.6.32-5-amd64. The problem appears at the "make" step with error message:

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.