【问题标题】:Plotting multiple IP addresses on world map using R使用 R 在世界地图上绘制多个 IP 地址
【发布时间】:2014-08-13 17:26:14
【问题描述】:

我从参与者那里提取了一个包含 160 多个 IP 地址的列表,用于我想在世界地图上绘制的调查。想知道是否有一个 R 包。我在 CSV 列中也有 IP。

【问题讨论】:

  • 使用外部服务可以很好地定位少数地址。我有一个 pkg - gitlab.dds.ec/public/projects/bob.rudis/iptools - 它使用基于 Rcpp 的包中的 maxmind C API 来进行地理转换。但是,通常在地图上绘制 IP 地址通常没有什么效果,从surveymonkey (et al) CSV 日志中绘制 IP 地址更是如此。有人可能在出差或使用 Tor 时填写了表格,那么为什么要从 IP 日志中标出他们在调查时(或可能曾经)在哪里?最后,按国家/地区或 CC+次区域划分的条形图会更好 IMO

标签: r ggplot2 geolocation


【解决方案1】:

这是一种使用www.freegeoip.net 对IP 地址进行地理编码,并使用ggplot 制作地图的方法。

# some IP addresses - you have this already...
ips <- c(Louvre           ="213.139.122.103",
         British.Museum   ="195.224.71.221",
         Museo.del.Prado  ="213.27.146.137",
         Grand.Egyptian   ="163.121.93.15",
         Hermitage.Museum ="213.152.151.197",
         MBNA             ="200.218.240.120",
         Sydney.Museum    ="54.252.89.136",
         MOMA             ="63.117.124.131")

# you start here...
library(XML)
library(httr)
library(ggplot2)
get.geocode <- function(ip) {  # returns lat/long given an ip address
  url   <- "http://www.freegeoip.net"
  xml   <- content(GET(url,path=paste("xml",ip,sep="/")),type="text/xml")
  xpath <- c(lat="//Latitude",long="//Longitude")
  sapply(xpath,function(xp) as.numeric(xmlValue(xml[xp][[1]])))
}
locs <- data.frame(t(sapply(ips,get.geocode)))
library(ggplot2)
ggplot(locs, aes(x=long,y=lat))+ 
  borders("world", color="grey50", fill="grey90")+
  geom_point(color="red", size=3)+
  labs(x="",y="")+
  theme_bw() + theme(axis.text=element_blank(),axis.ticks=element_blank())+
  coord_fixed()

注意事项。 RDSTK 包是 Data Science Toolkit API 的包装器。虽然我喜欢这个想法,但我发现 DSK 有点古怪。除其他外,它不一定会找到每个合法的 IP 地址。例如,当我使用上面的数据集运行另一个答案时,它只找到 8 个 IP 中的 4 个。此外,他们使用 POST 一次获取多个结果的“批量”API 的工作方式不一定与它的 GET 接口(每个 http 请求获取一个结果)相同。见this post

如果这是针对客户的,我会使用其中一种商业网络服务(例如MaxMind)来对 IP 地址进行地理编码并从中工作。只需 160 个 IP,您几乎不需要花费任何费用。

另外,borders(...) 使用 mapdata 包中的 worldHires 数据集,如您所见,这不是很好。我倾向于下载更好的数据集,例如world map on GADM

【讨论】:

  • 太棒了。把所有的ip都用括号和逗号括起来有点麻烦,但是很管用
  • 不确定你的意思。无需在 ips 周围加上括号或逗号。
  • 我的意思是它似乎只能以这种格式工作:ips
  • 这是真的,但 ips 来自哪里?如果您使用read.table(...)read.csv(...) 从文本文件将它们读入R,它们将导入一个字符(或更可能的因素)。无论哪种情况,代码都应该工作。
【解决方案2】:

这是一种方法:

# grab example data
library(XML)
tab <- readHTMLTable("http://www.ip-adress.com/proxy_list/", which = 1)[-1, c(1, 3)]
names(tab) <- c("ip.address", "country")
tab$ip.address <- sub(":.*", "", tab$ip.address)

# ip to location
library(RDSTK)
loc <- ip2coordinates(ip = paste(tab$ip.address, collapse=", "))
df <- merge(x = tab, y = loc, by = "ip.address", all.x = TRUE)
na.omit(df) # print matches

# plot
library(rworldmap)
par(mar = rep(0, 4)) 
plot(getMap())
with(df, points(x = longitude, y = latitude, col = "red", pch = 19))

您可能需要安装包XMLRDSTKrworldmap

【讨论】:

    【解决方案3】:

    您需要将工作分解为多个流程。

    1. 将 IP 映射到经纬度坐标。 参考Geocode an IP address? 或寻找提供此功能的 API。

    2. 使用 httr::get 或 Rcurl 将您的 IP 传递给 API。 返回格式将是 JSON 或 XML(大多数情况下),您需要 要解析为经纬度的 RJSONIO 或 XML 库

    3. 世界地图 您可以使用地图、rworldmap 包(或 ggmap...)来创建地图。然后项目 您的经纬度使用您选择的任何方法(如点..)

    您提出的问题比您想象的要复杂,您可能想问 单独的问题或在上述每个步骤中搜索答案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-06
      • 2013-05-25
      • 1970-01-01
      相关资源
      最近更新 更多