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