Geolocate IP addresses in R

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.

11 thoughts on “Geolocate IP addresses in R

    • 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

  1. Pingback: Convert IP addresses to geolocation, latitude and longitude etc etc | Robert Grant's stats blog

  2. Pingback: (zz) Convert IP addresses to geolocation, latitude and longitude etc etc | Eva's Infographics

  3. Pingback: Mapping the ISP’s Serving Egypt During November 2009 and September 2011 | Forays from Mathematics into Data Science

  4. Pingback: Geocode IP Addresses in R | Data Analysis Tools

  5. Pingback: IP-based Geo-location in Tableau (New! Now with more R!) | Tableau Love

  6. Pingback: Mapping Web Traffic: A Post on a Previous Post – data and photos

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s