google地理编码和R中的haversine距离计算
我正在使用google地理编码和R中的haversine距离计算,r,geocoding,google-geocoder,R,Geocoding,Google Geocoder,我正在使用ggmap包中的geocode函数对国家名称进行地理编码,然后将它们传递到geosphere库中的distHaversine以计算两国之间的距离 我的数据样本如下: Country.Value Address.Country 1: United States United States 2: Cyprus
ggmap
包中的geocode
函数对国家名称进行地理编码,然后将它们传递到geosphere
库中的distHaversine
以计算两国之间的距离
我的数据样本如下:
Country.Value Address.Country
1: United States United States
2: Cyprus United States
3: Indonesia United States
4: Tanzania Tanzania
5: Madagascar United States
6: Belize Canada
7: Argentina Argentina
8: Egypt Egypt
9: South Africa South Africa
10: Paraguay Paraguay
我还使用了if-else语句,试图保持在免费谷歌地图地理编码器设置的地理编码限制内。我的代码如下:
for(i in 1:nrow(df)) {
row<-df.cont.long[i,]
src_lon<- 0.0
src_lat<- 0.0
trgt_lon<- 0.0
trgt_lat<- 0.0
if((row$Country.Value=='United States')){ #Reduce geocoding requirements
trgt_lon<- -95.7129
trgt_lat<- 37.0902
}
else if((row$Address.Country=='United States')){ #Reduce Geocoding Requirements
src_lon<- -95.7129
src_lat<- 37.0902
}
else if((row$Country.Value=='Canada')){ #Reduce geocoding requirements
trgt_lon<- -106.3468
trgt_lat<- 56.1304
}
else if((row$Primary.Address.Country=='Canada')){ #Reduce Geocoding Requirements
src_lon<- -106.3468
src_lat<- 56.1304
}
else if(row$Country.Value == row$Address.Country){ #Reduce Geocoding Requirements
# trgt<-geocode(row$Country.Value)
# trgt_lon<-as.numeric(trgt$lon)
# trgt_lat<-as.numeric(trgt$lat)
# src_lon<-as.numeric(trgt$lon)
# src_lat<-as.numeric(trgt$lat)
}
else{
trgt<-geocode(row$Country.Value, output=c("latlon"))
trgt_lon<-as.numeric(trgt$lon)
trgt_lat<-as.numeric(trgt$lat)
src<-geocode(row$Address.Country)
src_lon<-as.numeric(src$lon)
src_lat<-as.numeric(src$lat)
}
print(i)
print(c(row$Address.Country, src_lon, src_lat))
print(c(row$Country.Value, trgt_lon, trgt_lat))
print(distHaversine( p1=c(as.numeric(src$lon), as.numeric(src$lat)), p2=c(as.numeric(trgt$lon), as.numeric(trgt$lat)) ))
}
for(1中的i:nrow(df)){
行您正在使用的函数是矢量化的,所以您真正需要的是
library(ggmap)
library(geosphere)
distHaversine(geocode(as.character(df$Country.Value)),
geocode(as.character(df$Address.Country)))
# [1] 0 10432624 14978567 0 15868544 4588708 0 0 0 0
请注意,as.character
s的存在是因为ggmap::geocode
不喜欢这些因素。结果很有意义:
df$distance <- distHaversine(geocode(as.character(df$Country.Value), source = 'dsk'),
geocode(as.character(df$Address.Country), source = 'dsk'))
df
# Country.Value Address.Country distance
# 1 United States United States 0
# 2 Cyprus United States 10340427
# 3 Indonesia United States 14574480
# 4 Tanzania Tanzania 0
# 5 Madagascar United States 16085178
# 6 Belize Canada 5172279
# 7 Argentina Argentina 0
# 8 Egypt Egypt 0
# 9 South Africa South Africa 0
# 10 Paraguay Paraguay 0
或按行:
apply(df, 1, function(x){distHaversine(tmap::geocode_OSM(x['Country.Value'])$coords,
tmap::geocode_OSM(x['Address.Country'])$coords)})
# [1] 0 10448111 14794618 0 16110917 5156823 0 0 0 0
和coords
数据的子集。还要注意的是,Google、DSK和OSM都为每个国家选择不同的中心,因此产生的距离相差一定距离。您使用的函数是矢量化的,所以您真正需要的是
library(ggmap)
library(geosphere)
distHaversine(geocode(as.character(df$Country.Value)),
geocode(as.character(df$Address.Country)))
# [1] 0 10432624 14978567 0 15868544 4588708 0 0 0 0
请注意,as.character
s的存在是因为ggmap::geocode
不喜欢这些因素。结果很有意义:
df$distance <- distHaversine(geocode(as.character(df$Country.Value), source = 'dsk'),
geocode(as.character(df$Address.Country), source = 'dsk'))
df
# Country.Value Address.Country distance
# 1 United States United States 0
# 2 Cyprus United States 10340427
# 3 Indonesia United States 14574480
# 4 Tanzania Tanzania 0
# 5 Madagascar United States 16085178
# 6 Belize Canada 5172279
# 7 Argentina Argentina 0
# 8 Egypt Egypt 0
# 9 South Africa South Africa 0
# 10 Paraguay Paraguay 0
或按行:
apply(df, 1, function(x){distHaversine(tmap::geocode_OSM(x['Country.Value'])$coords,
tmap::geocode_OSM(x['Address.Country'])$coords)})
# [1] 0 10448111 14794618 0 16110917 5156823 0 0 0 0
和coords
数据的子集。还要注意的是,Google、DSK和OSM都为每个国家选择不同的中心,因此产生的距离会相差一定距离。有没有办法将if-else语句合并到矢量化解决方案中?否则,我将超过Google maps geocoder的2500个限制。使用源代码=“dsk”
,你不必担心。我相信它也可以用dsk自动缓存。或者,如果你愿意,你可以根据地图数据计算你自己的质心。即使在添加source='dsk'
之后。我得到了一个错误:谷歌将非商业用途的请求限制为每天2500个。只要我运行codeOdd,但它确实有一个override_limit
参数可能会解决您的问题。还有其他地理编码功能/服务,例如使用OpenStreetMap数据的tmap::geocode_OSM
。tmap似乎是一个更好的解决方案。我正在使用以下代码:df$dist是否有办法将if-else语句合并到矢量化解决方案中e、 我将超过google maps geocoder的2500个限制。使用source='dsk'
,您不必担心。我相信它也会使用dsk自动缓存。或者,如果您愿意,您可以根据地图数据计算您自己的质心。即使在添加source='dsk'
之后。我遇到了一个错误:google将请求限制为2500个请求用于非商业用途。只要我运行codeOdd,但它确实有一个override\u limit
参数,可能会解决您的问题。还有其他地理编码功能/服务,例如tmap::geocode\u OSM
,它使用OpenStreetMap数据。tmap似乎是一个更好的解决方案。我正在使用以下代码:df$dist