I am trying to implement tryCatch with a while loop in R, but have been running into issues. I have tried to implement a number of the proposed solutions (which revolve around for loops), but with no success.
Essentially I am querying an API with R and looping through a number of relevant parameters (longitudes and latitudes to be precise). The reason why I need a tryCatch block is because sometimes the URL request will fail, which in turn stops the script running. What I want to be able to do is to ignore the error, increase the looping counter by 1 and continue extraction.
The while loop I have set up is (FYI - length refers to length of dataframe being looped over):
i <- 1
while(i <= length) {
x_cord <- geocode_area$X[i]
y_cord <- geocode_area$Y[i]
target <- getUrl(x_cord,y_cord)
dat <- fromJSON(target)
geocode_area$Block[i] <- dat$result$geographies$`2010 Census Blocks`[[1]]$BLOCK
print(paste(i/length*100,"% completed",sep=""))
print(dat$result$geographies$`2010 Census Blocks`[[1]]$BLOCK)
i <- i + 1
}
The getUrl() function is defined as:
getUrl <- function(x,y) {
root <- "http://geocoding.geo.census.gov/geocoder/geographies/coordinates?"
u <- paste0(root,"x=", x,"&y=", y,"&benchmark=4&vintage=4&format=json")
return(URLencode(u))
}
The input data.frame to the while loop looks like so (note I have thrown in the character strings to simulate an error to test that tryCatch is working):
X Y Block
1 -122.425891675136 37.7745985956747 0
2 -122.42436302145 37.8004143219856 0
3 -122.426995326766 37.8008726327692 0
4 -122.438737622757 37.7715411720578 0
5 abc zsads 0
I have tried a number of the SO and other solutions, but the results do not seem to be working properly. Can anyone help?
Thanks!
Jack
As a general note - your code is kind of weird. I would recommend either a for loop, or possibly better, a function that does this stuff. But you can make your loop work.
# A minimal working version
library(RJSONIO)
options(stringsAsFactors = FALSE)
# Create a data frame with the example data
geocode_area <- data.frame(X = c("-122.425891675136","-122.42436302145","-122.426995326766","-122.438737622757","abc"),
Y = c("37.7745985956747","37.8004143219856","37.8008726327692","37.7715411720578","zsads"),
Block = c(0,0,0,0,0))
# Your old function, unchanged
getUrl <- function(x,y) {
root <- "http://geocoding.geo.census.gov/geocoder/geographies/coordinates?"
u <- paste0(root,"x=", x,"&y=", y,"&benchmark=4&vintage=4&format=json")
return(URLencode(u))
}
# Getting the length parameter
length <- nrow(geocode_area)
i <- 1
while(i <= length) {
x_cord <- geocode_area$X[i]
y_cord <- geocode_area$Y[i]
target <- getUrl(x_cord,y_cord)
# Here be new code
# Do a try(), with silent = TRUE, which suppresses outputs to STDERR
# In principle, this is dangerous - a better approach is to strip out the offending data before invoking it
# Errors are, after all, there for a reason
dat <- try(fromJSON(target),silent = TRUE)
# Now, we conditionally complete the next steps
# If the class of dat is not a try-error, perform your normal operations
# Otherwise, bypass and print a note to the console
if(class(dat) != "try-error") {
geocode_area$Block[i] <- dat$result$geographies$`2010 Census Blocks`[[1]]$BLOCK
print(paste(i/length*100,"% completed",sep=""))
print(dat$result$geographies$`2010 Census Blocks`[[1]]$BLOCK)
} else if (class(dat) == "try-error") {print("Error encountered, bypassing")}
i <- i + 1
}
EDITED TO ADD: Obviously, this uses try() instead of tryCatch(). However, as the poster ended up using try() and this may represent a different way to do it, I thought I'd leave it up.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With