Waht
Waht

Reputation: 301

Loop too fast for read.csv

I wrote a loop that reads the csv files and rbind them.

vec1 = c(0,1,3,5,9)
vec2 = c("mom", "dad")
c = data.frame()

for(i in length(vec1))
{
  for (j in length(vec2))
  {
    dir = paste("../data/year ", vec1[i], "/ff_", vec2[j], "_cb", vec1[i], ".csv", sep="")
    a = read.csv(dir)
    Sys.sleep(3)
    c = rbind(c,a)

  }

}

However, when I try to execute it, only the result from the last iteration is there. (i.e. a has the value from the last iteration, and c is the same as a).

I though this is because the loop is too fast, that it does not wait for read.csv to finish before going to the next. Therefore, I put a sys.sleep(3) in there.

However, the same problem persists. Moreover, I was able to set i, j manually to complete this task, so the syntax should be correct, but I don't know what the problem is.

Thanks!

Upvotes: 2

Views: 182

Answers (2)

Joshua Ulrich
Joshua Ulrich

Reputation: 176718

As Dave2e noted in their answer, your loops are incorrect. While their answer is correct, it is better to use seq_along to avoid problems if vec1 or vec2 are zero-length vectors. For example:

vec1 <- integer()
vec2 <- c("mom", "dad")

for(i in 1:length(vec1))
{
  for (j in 1:length(vec2))
  {
    print(paste(vec1[i], vec2[j]))
  }
}
#[1] "NA mom"
#[1] "NA dad"
#[1] " mom"
#[1] " dad"

When you really wanted no iterations:

for(i in seq_along(vec1))
{
  for (j in seq_along(vec2))
  {
    print(paste(vec1[i], vec2[j]))
  }
}

In this specific case, you don't even need an integer iterator. You can simply loop over the vector elements themselves.

vec1 <- c(0, 1)
vec2 <- c("mom", "dad")

for(v1 in vec1)
{
  for (v2 in vec2)
  {
    print(paste(v1, v2))
  }
}
# [1] "0 mom"
# [1] "0 dad"
# [1] "1 mom"
# [1] "1 dad"

Upvotes: 4

Dave2e
Dave2e

Reputation: 24139

Your loops are incorrect. for(i in length(vec1)) will only perform one iteration. The correct format is: for(i in 1:length(vec1)) For example try this:

vec1 = c(0,1,3,5,9)
vec2 = c("mom", "dad")
for(i in 1:length(vec1))
{
  for (j in 1:length(vec2))
  {
    print(paste(i, j))   
  }  
}

Then repeat the example with your statements.

Upvotes: 7

Related Questions