0

I need to generate the country codes from a list of IP addresses (around 300) and plot them on a map using R code for my MSc project.

I have tried rgeolocation but it's a no go on my R version 4.3.1 and maxmind doesn't work. Also tried iptocountry but that doesn't work either. I thought ip2location package would work, which I installed fine but then I can't seem to get the results I need, as maxmind isn't compatible with ip2location... I'm quite new to the coding game and tried to cobble together the below, but it errors at extracting the results with maxmind (obviously). I don't know what the alternative would be??..

Would be forever grateful if anyone could offer some advice / fix the code!

Thanks :) your girl, Steph

#Tried this but it errors on the results/maxmind line

#load the data set
options(scipen = 999)
options(max.print = 1000000)
data = readr::read_csv("C:/Users/Steph/Documents/ip_address.csv")
View(data)

#Load the package
library(ip2location)

#Step 2: Convert IP Address to Country Analysis

setwd("C:/Users/Steph/Documents")

ipdf <- read.csv("C:/Users/Steph/Documents/ip_address.csv")
ipmmdb <- system.file("extdata","GeoLite2-Country.mmdb", package = "ip2location")
results <- maxmind(ipdf$IP.Address, ipmmdb,"country_name") #error here

export.results <- data.frame(ipdf$IP.Address, results$country_name)
colnames(export.results) <- c("IP Address", "Country")

write.csv(export.results, "C:/Users/Steph/Documents/IP_to_Locationmmdb.csv")

#not sure how i can plot my file data on the map ...
plot_map(ips)
neilfws
  • 32,751
  • 5
  • 50
  • 63
  • You maximise your chance of getting a useful answer if you provide a minimal reproducible example. [This post](https://stackoverflow.com/help/minimal-reproducible-example) may help. Here, we need to see your data. We don't have access to your C drive, so can't run your code. Posting the results of `dput(data)` or `dput(head(data))` to your question is the ideal solution. – Limey Aug 14 '23 at 07:35

1 Answers1

1
# these are random IP addresses I got from https://catonmat.net/tools/generate-random-ip-addresses
df <- read.table(text="
ip_address
178.10.17.178
157.213.207.99
94.230.235.15
97.103.63.156
248.161.179.64
12.114.230.175
68.68.181.51
59.7.213.18
59.38.90.12
103.213.135.197", header = TRUE)

# load libraries
pacman::p_load(ip2location, reticulate, tidyverse)

# my computer has multiple versions of python installed, so I need to specify which one to use. reticulate uses one that doesn't have IP2Location installed, but I can't figure out which one it is lol
# replace this with your own python path if you have already installed IP2Location using pip but are still getting an error about IP2Location not being installed
use_python("/opt/homebrew/bin/python3")

# load IP2Location bin file
ip2location::open("/Users/me/Downloads/IP2LOCATION-LITE-DB11.BIN/IP2LOCATION-LITE-DB11.BIN")
df <- df |>
  mutate(details =  map(ip_address, get_all)) |> 
  unnest_wider(details) 

# df
# A tibble: 10 × 10
   ip_address      ip              country_short country_long            
   <chr>           <chr>           <chr>         <chr>                   
 1 178.10.17.178   178.10.17.178   DE            Germany                 
 2 157.213.207.99  157.213.207.99  US            United States of America
 3 94.230.235.15   94.230.235.15   UZ            Uzbekistan              
 4 97.103.63.156   97.103.63.156   US            United States of America
 5 248.161.179.64  248.161.179.64  -             -                       
 6 12.114.230.175  12.114.230.175  US            United States of America
 7 68.68.181.51    68.68.181.51    US            United States of America
 8 59.7.213.18     59.7.213.18     KR            Korea (Republic of)     
 9 59.38.90.12     59.38.90.12     CN            China                   
10 103.213.135.197 103.213.135.197 CN            China                   
   region      city       latitude  longitude  zipcode timezone
   <chr>       <chr>      <chr>     <chr>      <chr>   <chr>   
 1 Hessen      Eschborn   50.143517 8.570921   65760   +02:00  
 2 Ohio        Columbus   39.966381 -83.012772 43218   -04:00  
 3 Toshkent    Tashkent   41.264648 69.216270  700011  +05:00  
 4 Florida     Orlando    28.538340 -81.379242 32801   -04:00  
 5 -           -          0.000000  0.000000   -       -       
 6 New Jersey  Piscataway 40.554516 -74.460167 08854   -04:00  
 7 Tennessee   Camden     36.058815 -88.102158 38320   -05:00  
 8 Gyeonggi-do Seongnam   37.420624 127.126717 13118   +09:00  
 9 Guangdong   Foshan     23.026770 113.131477 528000  +08:00  
10 Jiangsu     Changzhou  31.783331 119.966667 213019  +08:00
plot_map(df$ip_address)

world map with IP addresses

Mark
  • 7,785
  • 2
  • 14
  • 34
  • Thanks so much for your feedback and the code you sent. Appreciate your speedy response! So it seems that I had the ip2location library installed in R, but i didn't have the latest python or ip2location installed either. I installed both but then it falls over... heavy sigh... trying to figure out where in the world is the bin file you mentioned (maybe i didn't install that either...) – Steph T Aug 07 '23 at 07:21
  • re: the falls over - what errors do you get? – Mark Aug 07 '23 at 07:23
  • re: the bin: it's from here (you need to register to get it) - https://lite.ip2location.com/database-download – Mark Aug 07 '23 at 07:24
  • It seems I haven't installed the ip2location module... i'm such a dummy dumb – Steph T Aug 07 '23 at 07:26
  • I signed up and downloaded the bin file to "C:\Users\Steph\Documents\IP2LOCATION-LITE-DB11.BIN" but the code doesn't seem to want to read it... I have essentially generated an empty map # load IP2Location bin file ip2location::open("C:/Users/Steph/Documents/IP2LOCATION-LITE-DB11.BIN"") df <- df |> mutate(details = map(ip_address, get_all)) |> unnest_wider(details) – Steph T Aug 07 '23 at 13:19
  • i downloaded python3 and IP2location, signed up and downloaded that bin file mentioned above but then it doesn't generate this: # df # A tibble: 10 × 10 ip_address ip country_short country_long 1 178.10.17.178 178.10.17.178 DE Germany etc etc – Steph T Aug 07 '23 at 13:21
  • am i missing something? appreciate your patience :) – Steph T Aug 07 '23 at 13:23
  • okay, a couple of things/questions: 1. the code should be `ip2location::open("C:/Users/Steph/Documents/IP2LOCATION-LITE-DB11.BIN")` (there was an extra quote mark in there 2. when you run that, do you get some kind of error? 3. what happens when you open df after running the `df <- df |> mutate(details = map...`etc. code? Do you have the extra columns? – Mark Aug 07 '23 at 13:41
  • Also re:patience- no worries! But also we haven't fixed it yet so don't get ahead of yourself you're doing well – Mark Aug 07 '23 at 13:46
  • when i run that quote (minus the extra quotation i get the following error: in py_run_string_impl(code, local, convert) : ModuleNotFoundError: No module named 'IP2Location' Run `reticulate::py_last_error()` for details. Do you think I need to install the IP2Location module in R or python? – Steph T Aug 07 '23 at 18:36
  • Then the df <- df |> mutate(details = map... Gives me this error: Error in `mutate()`: ℹ In argument: `details = map(ip_address, get_all)`. Caused by error: ! object 'ip_address' not found Run `rlang::last_trace()` to see where the error occurred. – Steph T Aug 07 '23 at 18:43
  • 1
    Finally worked out how to install the IP2Location module in Python. At the terminal in RStudio I ran 'pip install IP2Location'. Then was able to successfully run the code you sent @Mark Thanks for your help to a newbie coder! – Steph T Aug 11 '23 at 11:17
  • @StephT no worries! Glad I could help, and that is got solved – Mark Aug 11 '23 at 12:06
  • I thought I had replied to you ‍ sorry – Mark Aug 11 '23 at 12:07
  • no worries thanks! – Steph T Aug 11 '23 at 18:06