Reputation: 99
I have a very large table (n=2,723,860
) and I want to calculate positive wind direction (0 to 360 degrees) from negative wind direction (-180 to 180 degrees).
One of my loops, a for loop with a nested if and else if statement, takes forever to run (see below).
I am new to R and I am thinking that I just don't have this structured efficiently. Any help on how to better structure this so that it doesn't take so long (currently at 20 minutes and it still isn't done)?
for (j in 1:n){
if (Jun012015$D[j] < 0){
Jun012015$D1[j] <- (Jun012015$D[j] * (-1))
} else if (Jun012015$D[j] > 0){
Jun012015$D1[j] <- ((Jun012015$D[j] * (-1)) + 360)
} else {
Jun012015$D1[j] <- 0
}
}
Upvotes: 2
Views: 2233
Reputation: 886938
We could also use ifelse
(but this will be considerably slower compared to @Dason's solution).
with(Jun012015, ifelse(D1 < 0, D1 * -1, ifelse(D1 > 0, D1 * -1 +360, 0)))
Or as @Dason suggested, a single ifelse
can also fit into
with(Jun012015, ifelse(D1 <=0, D1 * -1, D1 * -1 + 360))
as 0 * (anynumber) = 0.
Upvotes: 1
Reputation: 91
Try using ifelse rather than nested if else statements.
for(j in 1:n){
ifelse(Jun012015$D[j] < 0, Jun012015$D[j]*(-1),
ifelse(Jun012015$D[j] > 0, (Jun012015$D[j] * (-1)) + 360, 0)
}
Please provide some sample data that you're running this loop on to help give benchmarked answers. The apply family of functions always work better than loops in R.
Upvotes: -2
Reputation: 61903
I hope docendo discimus decides to reopen their answer because it was good. Here is the code from their answer (which I will remove if they reopen theirs)
idx1 <- Jun012015$D < 0
idx2 <- Jun012015$D > 0
idx3 <- Jun012015$D == 0
Jun012015$D1[idx1] <- Jun012015$D[idx1] * (-1)
Jun012015$D1[idx2] <- (Jun012015$D[idx2] * (-1)) + 360
Jun012015$D1[idx3] <- 0
I prefer this answer for people that don't grasp vectorization yet. It works and shouldn't be too much slower than mine (shown below). But I think it shows the process much more clearly and could help OP more in the future than mine which probably just looks like a mystery to somebody that is still using for loops and if statements. But here is my one-liner that should get it done:
Jun012015$D*(-1) + 360*(Jun012015$D > 0)
you would need to store that into a variable or overwrite Jun012015$D with it.
Upvotes: 7