I am using the geonames
package in R to do a reverse geocode search (GNcountryCode
) to find the nearest country to my inputs. My inputs are not very precise and are located in water near land. geonames
allows for a search within a buffer (km) of the input location.
I was trying to use mapply
to expedite retrieving country names from a long list of input locations. However, the limits on buffer size still leave some input locations without a country. To permit mapply
to continue running I used tryCatch
to prevent mapply
from stopping.
However, this results in a non-list entry ("Error") in the overall list of lists (output below). As such, when trying to use data.table::rbindlist
I get the following error: "Item n of list input is not a data.frame, data.table or list"
How can I otherwise loop or vectorize GNcountryCode
to get the nearest country name to the input location and then add this name back (cbind) to the original data frame (with the understanding that some locations will not be matched to a country)?
library(geonames)# requires a username for some functionality
Latitude <- c("32.75", "33.75", "33.75", "34.25", "34.25", "36.75")
Longitude <- c("-17.25", "-52.25", "-51.75", "-52.25", "-51.75", "-25.25")
# df <- cbind.data.frame(Latitude, Longitude)
MyFun <- function(x,y) {
MyRes <- tryCatch(GNcountryCode(lat=x, lng=y, radius=250), error = function(e) paste("Error"))
#print(MyRes)
return(MyRes)
}
MyResult <- mapply(MyFun, Latitude, Longitude)
data.table::rbindlist(MyResult, fill = TRUE)
#cbind(df, data.table::rbindlist(MyResult, fill = TRUE))
#Ouput
$`32.75`
$`32.75`$`languages`
[1] "pt-PT,mwl"
$`32.75`$distance
[1] "1.96436"
$`32.75`$countryCode
[1] "PT"
$`32.75`$countryName
[1] "Portuguese Republic"
$`33.75`
[1] "Error"
$`33.75`
[1] "Error"
$`34.25`
[1] "Error"
$`34.25`
[1] "Error"
$`36.75`
$`36.75`$`languages`
[1] "pt-PT,mwl"
$`36.75`$distance
[1] "22.63538"
$`36.75`$countryCode
[1] "PT"
$`36.75`$countryName
[1] "Portuguese Republic"
set the error parameter to return NA (and you might also want to pull out just the country name from the return of results that work)...
library(geonames)# requires a username for some functionality
Latitude <- c("32.75", "33.75", "33.75", "34.25", "34.25", "36.75")
Longitude <- c("-17.25", "-52.25", "-51.75", "-52.25", "-51.75", "-25.25")
df <- cbind.data.frame(Latitude, Longitude)
MyFun <- function(x,y) {
tryCatch(GNcountryCode(lat = x, lng = y, radius = 250)$countryName, error = function(e) NA_character_)
}
df$countryname <- mapply(MyFun, Latitude, Longitude)
df
# Latitude Longitude countryname
# 1 32.75 -17.25 Portuguese Republic
# 2 33.75 -52.25 <NA>
# 3 33.75 -51.75 <NA>
# 4 34.25 -52.25 <NA>
# 5 34.25 -51.75 <NA>
# 6 36.75 -25.25 Portuguese Republic