0

I want to loop some code that checks the latitude and longitude of one row of a df1 against all the rows of latitude and longitude of df2 for their distance, and then filters for those distances less than 500. I want to then drop down to the next row of df1 and do the same task.

I can achieve it for the first row, but I haven't been successful in looping it.

I have tried wrapping it in a loop function:

for (i in nrow(df3$value)){ 
df <- df2 %>% 
  filter(distHaversine(c(Longitude, Latitude), c(df3$Longitude[i], df3$Latitude[i])) <= 500)

df <- data.frame(df, df3$value[i])

}

but that hasn't been successful.

This code below returns when copied into the console returns the correct information against 1 row of df3. I want to be able to run it against all 75 rows of df3.

df <- df2 %>% 
  filter(distHaversine(c(Longitude, Latitude), c(df3$Longitude[1], df3$Latitude[1])) <= 500)

df <- data.frame(df, df3$value[1])

1 Answers1

0

First, I recommend reading this Q&A about reproducible examples for writing your future questions. For example, I don't know what package you are using for the distHaversine function, so I cannot be sure about its arguments. The easier you make for others to answer your question, the most likely you are getting the answer you need.

There are a couple of mistakes on your for loop call:

  • You need to use a number sequence to loop over, not a single number
  • nrow() is used for 2-dimensional arrays, like matrices or dataframes. For a vector like df3$value you must use length(). Assuming df3 is a data.frame object, you can easily check that nrow(df3$value) returns NULL.

So, your problem is more basic: the for loop call is not even running. That is why your second code chunk gives you the result you want, but the first do not.

for(i in 1:nrow(df3)) { }

# or

for(i in 1:length(df3$x)) { }

# or (maybe better)

for(i in seq_along(df3$value)) { }

But, I think you should avoid using for loops when writing R code. There is nothing wrong with it, but you should abuse R's functional programming and vectorised solutions for concise and efficient code.

For example, you could write a function based on the second code and combine it with an lapply function or purrr package's map family (in this case, purrr::map_dfr()). I highly recommend getting used with the latter, as it is much more robust.

Gabriel M. Silva
  • 642
  • 4
  • 10
  • Thanks for the reply! I think I'll definitely have to look into map_dfr(). I'm a little confused by it right now, but I'll look at producing a reprex and come back if I'm still confused! Thanks for the help :) – electricfalcon Jul 11 '19 at 15:09