簡體   English   中英

在R中進行批量地理編碼時,使用“apply”系列中的相應函數

[英]Using the appropriate function from the 'apply' family when batch geocoding in R

目標:向R傳遞一個街道地址向量,並返回一個三向量數據幀,其中第一個向量是街道地址(“Street.Address”),第二個向量是緯度(“Lat”),第三個向量是經度(“Lng”)。 為簡單起見,我只使用四個地址; 也就是說,向量的長度是4。

方法:我使用Jitender Aswani的代碼使用Google Maps的API創建地理編碼功能。 該功能非常出色,我能夠找到我選擇的任何地址的緯度/經度。 編碼:

getGeoCode <- function(address)
{ 
  #Load library
  library("RJSONIO")

  #Encode URL parameters
  address <- gsub(' ','%20',address)

  #Open connection
  connectStr <- paste('http://maps.google.com/maps/api/geocode/json?sensor=false&address=',address, sep="") 
  con <- url(connectStr)
  data.json <- fromJSON(paste(readLines(con), collapse=""))
  close(con)

  #Flatten the received JSON
  data.json <- unlist(data.json)
  lat <- data.json["results.geometry.location.lat"]
  lng <- data.json["results.geometry.location.lng"]
  gcodes <- c(lat, lng)
  names(gcodes) <- c("Lat", "Lng")
  return (gcodes)
}

geocodes<-getGeoCodes("Palo Alto, California")
geocodes

        Lat            Lng 
"37.4418834" "-122.1430195" 

嘗試在后續代碼中調用該函數時遇到了困難。 讓我們調用原始的一列對象“data.object”。 當我使用Aswani提供的以下代碼時......

data.object <- with(data.object, data.frame(Street.Address, lapply(Street.Address, function(val){getGeoCode(val)})))

...我希望函數返回一個長度為4的三列數據幀,其中column1是街道地址,column2是緯度,column3是經度:

    Street.Address                                  Lat            Lng
[1] 3625 1ST AVE S SEATTLE WA 98134           47.571010    -122.334447
[2] 2119 RAINIER AVE S SEATTLE WA 98144       47.584136    -122.302744
[3] 9660 16TH AVE SW SEATTLE WA 98106         47.516180    -122.355138
[4] 8300 RAINIER AVE S SEATTLE WA 98118       47.529750    -122.270010

相反,我得到一個五列數據幀,其中第二列中的值在第一個地址'緯度和第一個地址'經度之間交替,第三列中的值在第二個地址'緯度和第二個地址'之間交替經度,等等:

    Street.Address                           column2        column3      column4    column5
[1] 3625 1ST AVE S SEATTLE WA 98134        47.571010      47.584136    47.516180    47.529750
[2] 2119 RAINIER AVE S SEATTLE WA 98144  -122.334447    -122.302744  -122.355138  -122.270010
[3] 9660 16TH AVE SW SEATTLE WA 98106      47.571010      47.584136    47.516180    47.529750
[4] 8300 RAINIER AVE S SEATTLE WA 98118  -122.334447    -122.302744  -122.355138  -122.270010

我嘗試使用with(),within(),apply()和lapply()函數的不同組合重寫命令,我不能R返回一個簡單的三列數據幀。 我知道我忽視了一些顯而易見的事情,但我似乎無法弄明白。

Lapply返回一個列表,sapply是一個用戶友好的lapply版本,默認情況下返回一個向量或矩陣。 您可以使用sapply()然后使用t():

data.object <- with(data.object, data.frame(Street.Address, t(sapply(Street.Address, function(val){getGeoCode(val)}))))

有一篇非常棒的帖子解釋了lapply函數系列之間的lapply R分組功能:sapply vs. lapply vs. apply。 vs. tapply vs. by vs. aggregate 考慮到你的情況似乎問題是你想要lapply返回數據幀的行但返回列表。 您可以使用sapply但返回向量而不是行。 你可以做的最好的事情是使用sapply並將矢量轉換為你想要的尺寸的矩陣,或者unlist lapply並做同樣的事情。 讓我們嘗試第一個選項。

addressmat=matrix(sapply(address, function(val){append(val,as.numeric(getGeoCode(val)))}),4,3, byrow=TRUE) 
addressmat
[,1]                                  [,2]         [,3]          
[1,] "3625 1ST AVE S SEATTLE WA 98134"     "47.5698918" "-122.3360067"
[2,] "2119 RAINIER AVE S SEATTLE WA 98144" "47.583897"  "-122.30269"  
[3,] "9660 16TH AVE SW SEATTLE WA 98106"   "47.5159917" "-122.3551272"
[4,] "8300 RAINIER AVE S SEATTLE WA 98118" "47.5295467" "-122.2699776"

這不會返回colnames,但這很容易解決。

colnames(addressmat) <- c("Street.Address","Lat","Lng")

另一種選擇是Vectorize

getGeoCodes <- Vectorize(getGeoCode)
x <- c(
  "3625 1ST AVE S SEATTLE WA 98134", 
  "2119 RAINIER AVE S SEATTLE WA 98144", 
  "9660 16TH AVE SW SEATTLE WA 98106"
)
locations <- getGeoCodes(x) # a matrix
result <- data.frame(
   StreetAdress=x,
   Lat=as.numeric(locations["Lat",]),
   Lng=as.numeric(locations["Lng",])
)
rownames(result) <- NULL

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM