2013-11-26 17 views
0

我一直在使用啓發式安德魯博客和這StackOverflow Question這真棒代碼。修改R中的函數以添加ID信息?

我想做一個簡單的修改,以便我的最終輸出也有來自原始數據框的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功能是正確的代碼,但我不知道怎麼樣。

有人可以幫我嗎?

回答

0

編輯 - 更新,只需添加一個ID列

添加在你的代碼的結束,只是查找IP,並且將標識作爲新列:

outcomes<-data.frame(outcomes) 
outcomes$ID<-apply(outcomes,1,FUN=function(x)test1$ID[match(x["ip"],test1$IP)]) 

** * ** * ** *以前的答案* ** * ** * ** * ** * ** * *

的問題,如果你改變的功能是,你會改變形狀數據進入並將需要相當重要地重寫。

如果您只是想將結果添加到結果列中,爲什麼不嘗試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  432 
+0

感謝@Troy。但是,如果我有多個具有相同IP的用戶,會發生什麼? – Ignacio

+0

嗨@Ignacio,剛剛更新了答案,以便它可以重複使用... – Troy