This R function uses the free freegeoip.net geocoding service to resolve an IP address (or a vector of them) into country, region, city, zip, latitude, longitude, area and metro codes.
You will just need the rjson package, available from CRAN.
freegeoip <- function(ip, format = ifelse(length(ip)==1,'list','dataframe')) { if (1 == length(ip)) { # a single IP address require(rjson) url <- paste(c("http://freegeoip.net/json/", ip), collapse='') ret <- fromJSON(readLines(url, warn=FALSE)) if (format == 'dataframe') ret <- data.frame(t(unlist(ret))) return(ret) } else { ret <- data.frame() for (i in 1:length(ip)) { r <- freegeoip(ip[i], format="dataframe") ret <- rbind(ret, r) } return(ret) } }
And this demonstrates how to use it:
> # by default, a single IP address returns a list > freegeoip('184.26.100.110') $ip [1] "184.26.100.110" $country_code [1] "US" $country_name [1] "United States" $region_code [1] "MA" $region_name [1] "Massachusetts" $city [1] "Cambridge" $zipcode [1] "02142" $latitude [1] 42.3626 $longitude [1] -71.0843 $metro_code [1] "506" $areacode [1] "617" > > # multiple IP addresses always return a data frame > freegeoip(c('106.78.232.100','174.6.153.88')) ip country_code country_name region_code region_name 1 106.78.232.100 IN India 16 Maharashtra 2 174.6.153.88 CA Canada BC British Columbia city zipcode latitude longitude metro_code areacode 1 Mumbai 18.975 72.8258 2 Richmond 49.1667 -122.9667
This code could use more error handling and caching (memoization), but it should work fine for smaller batches. In case you are thinking of large-batch geolocation, freegeoip.net allows 10,000 queries per hour, and it seems a bit slow (at least, from my ISP).
UPDATE: Flodel has developed a generic error handling function for use with freegeoip.
Tested with R 2.15.2 on Ubuntu 13.04.
Hi Andrew,
Great function.
I’d be interested in adding it to my installr package (http://cran.r-project.org/web/packages/installr/), with full credit/link, of course.
Would that be o.k. with you?
(under what license do you release your code on the blog? you may wish to make it clear)
With regards,
Tal
Yes, this is fine. You may have this code under the GNU General Public License v2 or later, the same as installr.
Your suggestion is a good idea. I license longer projects under the GPL, but I haven’t given much thought to smaller bits of code.
Is the purpose to find the nearest server for downloading R?
Hi Andrew,
Great.
Regarding the purpose – very close. I actually already found a function for finding the best CRAN, and included it in the package (see the cranometer() function in the latest installr version).
What I wanted to do is to somehow combine it with the ip of the user, just for the fun of it (maybe somehow create a balloon world map).
I have a function for getting a user’s ip, and thank to you – I now have a function for getting the geo-info of the user based on his/her ip.
I have a draft of a post working on this (I’ll link to your post, as it is up).
Cheers 🙂
Tal
Pingback: Convert IP addresses to geolocation, latitude and longitude etc etc | Robert Grant's stats blog
Pingback: (zz) Convert IP addresses to geolocation, latitude and longitude etc etc | Eva's Infographics
Hi thanks for this code! It was really helpful.
Pingback: Mapping the ISP’s Serving Egypt During November 2009 and September 2011 | Forays from Mathematics into Data Science
Pingback: Geocode IP Addresses in R | Data Analysis Tools
Fantastic. Thanks much for this! Working well w/ large lists using the error handling you reference. J
Pingback: IP-based Geo-location in Tableau (New! Now with more R!) | Tableau Love
Pingback: Mapping Web Traffic: A Post on a Previous Post – data and photos