[英]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.