我一直在使用启发式Andrew blog和这个StackOverflow Question中的这段很棒的代码。
我想做一个简单的修改,以便我的最终输出也包含来自原始数据框的ID信息。这是我现在拥有的代码
test1 <- structure(list(ID = c("A123", "A123", "A125", "A126"),
IP = c("173.74.6.149", "109.189.227.94",
"50.27.115.146", "1.64.170.178")),
.Names = c("ID", "IP"), class = "data.frame",
row.names = c(NA, 4L))
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)
}
}
try.ip <- function(ip) suppressWarnings(try(freegeoip(ip), silent = TRUE))
outcomes <- lapply(test1$IP, try.ip)
is.ok <- function(x) !inherits(x, "try-error")
outcomes <- outcomes[sapply(outcomes, is.ok)]
outcomes <- do.call("rbind", outcomes)我认为正确的做法应该是修改freegeoip函数,但我不确定如何修改。
有人能帮帮我吗?
发布于 2013-11-26 23:48:53
编辑-已更新为仅添加ID列
在代码末尾添加,只需查找IP,并将ID添加为新列:
outcomes<-data.frame(outcomes)
outcomes$ID<-apply(outcomes,1,FUN=function(x)test1$ID[match(x["ip"],test1$IP)])*********PREVIOUS ANSWER*****************
如果您更改函数,问题是您将更改进入的数据的形状,并需要非常显著地重写它。
如果您希望它将结果添加到结果列,为什么不尝试merge()
idcols<-test1 # make a temp copy of the test1 table
colnames(idcols)<-c("id","ip") # make the ip column header identical to outcomes
merge(idcols,outcomes,by="ip") # merge by ip提供:
ip id country_code country_name region_code region_name city zipcode latitude longitude
1 109.189.227.94 A123 NO Norway 12 Oslo Oslo 59.9167 10.75
2 173.74.6.149 A123 US United States TX Texas Keller 76244 32.9346 -97.2517
3 50.27.115.146 A125 US United States TX Texas Midland 31.9974 -102.0779
metro_code areacode
1
2 623 817
3 633 432https://stackoverflow.com/questions/20220745
复制相似问题