使用';应用';在R中进行批量地理编码时的族
目标:将街道地址的单个向量传递给R,并返回一个三向量数据帧,其中第一个向量是街道地址(“street.address”),第二个向量是纬度(“Lat”),第三个向量是经度(“Lng”)。为了简单起见,我只使用了四个地址;也就是说,向量的长度是4 方法:我正在使用Google Maps的API创建一个地理编码函数。这个函数运行得非常出色,我可以找到我选择的任何地址的lat/long。守则:使用';应用';在R中进行批量地理编码时的族,r,geocoding,apply,R,Geocoding,Apply,目标:将街道地址的单个向量传递给R,并返回一个三向量数据帧,其中第一个向量是街道地址(“street.address”),第二个向量是纬度(“Lat”),第三个向量是经度(“Lng”)。为了简单起见,我只使用了四个地址;也就是说,向量的长度是4 方法:我正在使用Google Maps的API创建一个地理编码函数。这个函数运行得非常出色,我可以找到我选择的任何地址的lat/long。守则: getGeoCode <- function(address) { #Load library
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"
相反,我得到的是一个五列数据帧,其中第二列中的值在第一个地址“纬度”和第一个地址“经度”之间交替,第三列中的值在第二个地址“纬度”和第二个地址“经度”之间交替,依此类推:
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()、INTERNAIN()、apply()和lapply()函数的不同组合来重写该命令,但我无法使用R返回简单的三列数据帧。我知道我忽略了一些显而易见的东西,但我似乎无法理解。lappy返回一个列表,sapply是lappy的一个用户友好版本,默认情况下会返回一个向量或矩阵(如果合适)。您可以将sapply()与t()一起使用:
data.object有一篇很好的帖子解释了lappy
函数系列之间的差异。考虑到您的情况,问题似乎是您希望lappy
返回数据帧的行,但不返回其返回列表。您可以使用sapply
,但它返回向量而不是行。最好使用sapply
并将向量转换为所需维度的矩阵,或者取消列出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")
colnames(addressmat)另一个选项是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
getGeoCodes请参阅,以了解不受谷歌限制的地理编码器。
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(addressmat) <- c("Street.Address","Lat","Lng")
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