使用API函数填充数据表

问题描述 投票:0回答:1

我正在使用 geonames 包来请求国家/地区名称,我可以手动执行此操作,但我不明白如何为表中的每一行进行 API 调用。


loc2$country = GNcountryCode(loc2$lon, loc2$lat)$countryCode

我的目的是创建一个新列“国家”,并填充相应的代码,但它似乎简单地将所有纬度和经度连接到一个请求中。

我对这个问题的基本性质表示歉意。我完全没有使用 R 的经验。我不知道如何使函数调用工作。

这是第 1 行:

loc2[1,]
  latitudeE7 longitudeE7 accuracy                                                                           activity source  deviceTag
1  375800672  1268884670       22 ON_BICYCLE, ON_FOOT, IN_VEHICLE, UNKNOWN, 34, 30, 21, 13, 2014-01-24T10:12:51.748Z   WIFI 1521681206
                 timestamp velocity altitude verticalAccuracy platformType serverTimestamp deviceTimestamp batteryCharging formFactor heading
1 2014-01-24T10:12:50.011Z       NA       NA               NA         <NA>            <NA>            <NA>              NA       <NA>      NA
  deviceDesignation      lat      lon        day
1              <NA> 37.58007 126.8885 2014-01-24

背景:

官方要求我确定我在过去 10 年里访问过哪些国家以及停留时间。我经常旅行,经常以不同的方式前往/返回/前往另一个国家,甚至步行或骑自行车,因此我没有包含此信息的全面正式文件(如机票)。

我从未使用过 R,但经过一番阅读后,我认为分析我的 Google 位置历史记录是最简单的(尽管我经常启用飞行模式以延长电池寿命,所以即使这并不全面,但只是一个开始...... )

我有一个包含下载的 JSON 数据的数据表,并且通过仅选择唯一的日期将行数减少了 500 倍。 geonames 网站每小时允许 1000 次调用。

是的,我知道,一些(明智的)人会问,如果连我都不知道自己去过哪里,为什么我需要编译这些数据?我可以编造一个看似合理的虚构故事,但这本身已经成为一种痴迷。我已经 10 多年没有做过任何计算机工作了,所以我有点挣扎。

r data.table geolocation google-location-services geonames
1个回答
0
投票

Geonames 国家/地区代码 API 不支持批量请求,因此您只能在每次调用中包含单个坐标对。你可以通过以下方式处理这个问题

mapply()
-- 定义一个接受 2 个参数(纬度、经度)并从响应中提取
countryCode
的函数,将其用作
mapply()
的第一个参数;传递
lat
lon
向量作为第二个和第三个参数,
mapply
将循环遍历每个经纬度对,调用函数并返回带有结果的向量:

library(geonames)

# example locations:
loc2
#>          lon       lat
#> 1  -84.41688  77.88553
#> 2  -46.03540 -14.01990
#> 3  146.95480  59.73224
#> 4 -116.43957  47.22695
#> 5   60.64802  26.29448

loc2$country_gn <- 
  withr::with_options(
    list(geonamesUsername=YOUR_GEONAMES_USERNAME),
    mapply(\(lat, lon) GNcountryCode(lat, lon)$countryCode, loc2$lat, loc2$lon)
  )
loc2
#>          lon       lat country_gn
#> 1  -84.41688  77.88553         CA
#> 2  -46.03540 -14.01990         BR
#> 3  146.95480  59.73224         RU
#> 4 -116.43957  47.22695         US
#> 5   60.64802  26.29448         IR

尽管您可以在没有任何外部 API 的情况下处理此问题:获取国家/地区多边形数据集(例如通过

giscoR
rnaturalearth
)并使用
sf
包提供的空间连接来查找与您的点位置的匹配项:

library(sf)
library(giscoR)

# CNTR_RG_20M_2016_4326 dataset
world <- gisco_countries

# for high(er) resolution dataset from 2024:
# world <- gisco_get_countries(year = "2024", resolution = "01")

# convert loc2 to a spatial data frame;
# spatial join with world[, "CNTR_ID"] to match each loc2 location to a country polygon;
# extract CNTR_ID column;
loc2$country_cisco <- 
  st_join(
    st_as_sf(loc2, coords = c("lon", "lat"), crs = "WGS84"),
    world[, "CNTR_ID"]
  )$CNTR_ID

loc2
#>          lon       lat country_gn country_cisco
#> 1  -84.41688  77.88553         CA            CA
#> 2  -46.03540 -14.01990         BR            BR
#> 3  146.95480  59.73224         RU            RU
#> 4 -116.43957  47.22695         US            US
#> 5   60.64802  26.29448         IR            IR

请注意,不同的地理空间数据集在标记某些区域时可能会采取不同的方法,当您必须处理克里米亚或北塞浦路斯等位置时需要考虑这一点。这也适用于反向地理编码 API。


示例地点:

set.seed(1)
loc2 <- 
  sf::st_sample(giscoR::gisco_countries, 5) |> 
  sf::st_coordinates() |> 
  `colnames<-`(c("lon", "lat")) |> 
  as.data.frame()
  
loc2 <- structure(list(lon = c(-84.4168839239306, -46.0353998519945, 
146.954795316042, -116.439570855129, 60.6480190645839), lat = c(77.8855269367845, 
-14.0199015626225, 59.7322442944768, 47.226945417709, 26.2944803596838
)), class = "data.frame", row.names = c(NA, -5L))

创建于 2024-10-09,使用 reprex v2.1.1

© www.soinside.com 2019 - 2024. All rights reserved.