将经度和纬度与 R 中的国家相匹配
Match Longitude and Latitude with countries in R
我想找到两组不同坐标对应的国家。我的数据设置如下
lat_1
lon_1
lat_2
lon_2
40.71
74.00
51.50
0.127
37.77
122.4
48.85
2.352
我希望将结果存储在两个新列中。所以对于第一行,一列会说美国,另一列说英国。我曾尝试使用将我的坐标转换为国家/地区的函数,但我必须一次将该函数应用于一组,但我不确定它们是否匹配。同样使用该功能,它不会将其添加为额外的列。
我目前所拥有的在下面列出。
library(sp)
library(rworldmap)
library(dplyr)
coords2country = function(points)
{
countriesSP <- getMap(resolution='low')
pointsSP = SpatialPoints(points, proj4string=CRS(proj4string(countriesSP)))
indices = over(pointsSP, countriesSP)
indices$ADMIN
}
df <-read.csv("the_file",header=T, na.strings=c("","NA"))
coords2country(df)
当我这样做时,我得到了我上面描述的,而不是我正在寻找的。
所以这里是实现您正在寻找的内容的完整代码,使用最新的 sf
包作为基础。有关更多说明,请参阅代码随附的注释。
coords_df <- tibble::tribble(
~lat_1, ~lon_1, ~lat_2, ~lon_2,
40.71, 74, 51.5, 0.127,
37.77, 122.4, 48.85, 2.352
) %>%
dplyr::mutate(id = dplyr::row_number()) # create id column for each observation to ensure matching
# transform coordinates into a geo object (here, an sf object)
coords_sf <- coords_df %>%
tidyr::pivot_longer(cols = 1:4,
names_to = "coord_type",
values_to = "coord_data") %>%
tidyr::separate(col = coord_type, into = c("coord_type", "set"), sep = "_") %>%
tidyr::pivot_wider(names_from = coord_type, values_from = coord_data) %>%
sf::st_as_sf(coords = c("lon", "lat"), crs = 4326)
coords_sf
#> Simple feature collection with 4 features and 2 fields
#> Geometry type: POINT
#> Dimension: XY
#> Bounding box: xmin: 0.127 ymin: 37.77 xmax: 122.4 ymax: 51.5
#> Geodetic CRS: WGS 84
#> # A tibble: 4 x 3
#> id set geometry
#> * <int> <chr> <POINT [°]>
#> 1 1 1 (74 40.71)
#> 2 1 2 (0.127 51.5)
#> 3 2 1 (122.4 37.77)
#> 4 2 2 (2.352 48.85)
# get low resolution world map
world <- rnaturalearth::ne_countries(returnclass = "sf") %>%
dplyr::select(name) %>% # keep only country name
sf::st_transform(crs = 4326) %>%
st_make_valid() # useful as of 1.0 `sf` update, see https://github.com/r-spatial/sf/issues/1649
# join columns, if you want a country only if the point is within its borders
within_sf <- sf::st_join(x = coords_sf,
y = world,
join = sf::st_within)
within_sf
#> Simple feature collection with 4 features and 3 fields
#> Geometry type: POINT
#> Dimension: XY
#> Bounding box: xmin: 0.127 ymin: 37.77 xmax: 122.4 ymax: 51.5
#> Geodetic CRS: WGS 84
#> # A tibble: 4 x 4
#> id set geometry name
#> * <int> <chr> <POINT [°]> <chr>
#> 1 1 1 (74 40.71) Kyrgyzstan
#> 2 1 2 (0.127 51.5) United Kingdom
#> 3 2 1 (122.4 37.77) <NA>
#> 4 2 2 (2.352 48.85) France
# join columns, if you want the country closest to the point
# (even if the point is not within the border of any country)
nearest_sf <- sf::st_join(x = coords_sf,
y = world,
join = sf::st_nearest_feature)
nearest_sf
#> Simple feature collection with 4 features and 3 fields
#> Geometry type: POINT
#> Dimension: XY
#> Bounding box: xmin: 0.127 ymin: 37.77 xmax: 122.4 ymax: 51.5
#> Geodetic CRS: WGS 84
#> # A tibble: 4 x 4
#> id set geometry name
#> * <int> <chr> <POINT [°]> <chr>
#> 1 1 1 (74 40.71) Kyrgyzstan
#> 2 1 2 (0.127 51.5) United Kingdom
#> 3 2 1 (122.4 37.77) China
#> 4 2 2 (2.352 48.85) France
# now you have a country for each point.
# time to go back to your original format
# again a data frame, not any more an sf object
nearest_df <- dplyr::bind_cols(nearest_sf %>%
sf::st_drop_geometry(),
nearest_sf %>%
sf::st_coordinates() %>%
tibble::as_tibble() %>%
dplyr::rename(lon = X, lat = Y))
nearest_df
#> # A tibble: 4 x 5
#> id set name lon lat
#> <int> <chr> <chr> <dbl> <dbl>
#> 1 1 1 Kyrgyzstan 74 40.7
#> 2 1 2 United Kingdom 0.127 51.5
#> 3 2 1 China 122. 37.8
#> 4 2 2 France 2.35 48.8
output_df <- dplyr::bind_cols(nearest_df %>%
dplyr::filter(set == 1) %>%
dplyr::transmute(lat_1 = lat, lon_1 = lon, name_1 = name),
nearest_df %>%
dplyr::filter(set == 2) %>%
dplyr::transmute(lat_2 = lat, lon_2 = lon, name_2 = name))
output_df
#> # A tibble: 2 x 6
#> lat_1 lon_1 name_1 lat_2 lon_2 name_2
#> <dbl> <dbl> <chr> <dbl> <dbl> <chr>
#> 1 40.7 74 Kyrgyzstan 51.5 0.127 United Kingdom
#> 2 37.8 122. China 48.8 2.35 France
由 reprex package (v2.0.0)
于 2021-06-18 创建
作为参考,我也会在这里留下一个 link 到基于 shiny 的解决方案:
https::github.com/giocomai/latlon2map / here's an hosted version if you want to have a quick look: latlon2map.europeandatajournalism.eu。有了这个,你可以加载你的 csv,select 你的第一组经纬度,下载 table,用另一组再做一次,并将结果合并到 R 或其他地方。
上面的部分代码改编自同一包的ll_match()
函数。
我想找到两组不同坐标对应的国家。我的数据设置如下
lat_1 | lon_1 | lat_2 | lon_2 |
---|---|---|---|
40.71 | 74.00 | 51.50 | 0.127 |
37.77 | 122.4 | 48.85 | 2.352 |
我希望将结果存储在两个新列中。所以对于第一行,一列会说美国,另一列说英国。我曾尝试使用将我的坐标转换为国家/地区的函数,但我必须一次将该函数应用于一组,但我不确定它们是否匹配。同样使用该功能,它不会将其添加为额外的列。
我目前所拥有的在下面列出。
library(sp)
library(rworldmap)
library(dplyr)
coords2country = function(points)
{
countriesSP <- getMap(resolution='low')
pointsSP = SpatialPoints(points, proj4string=CRS(proj4string(countriesSP)))
indices = over(pointsSP, countriesSP)
indices$ADMIN
}
df <-read.csv("the_file",header=T, na.strings=c("","NA"))
coords2country(df)
当我这样做时,我得到了我上面描述的,而不是我正在寻找的。
所以这里是实现您正在寻找的内容的完整代码,使用最新的 sf
包作为基础。有关更多说明,请参阅代码随附的注释。
coords_df <- tibble::tribble(
~lat_1, ~lon_1, ~lat_2, ~lon_2,
40.71, 74, 51.5, 0.127,
37.77, 122.4, 48.85, 2.352
) %>%
dplyr::mutate(id = dplyr::row_number()) # create id column for each observation to ensure matching
# transform coordinates into a geo object (here, an sf object)
coords_sf <- coords_df %>%
tidyr::pivot_longer(cols = 1:4,
names_to = "coord_type",
values_to = "coord_data") %>%
tidyr::separate(col = coord_type, into = c("coord_type", "set"), sep = "_") %>%
tidyr::pivot_wider(names_from = coord_type, values_from = coord_data) %>%
sf::st_as_sf(coords = c("lon", "lat"), crs = 4326)
coords_sf
#> Simple feature collection with 4 features and 2 fields
#> Geometry type: POINT
#> Dimension: XY
#> Bounding box: xmin: 0.127 ymin: 37.77 xmax: 122.4 ymax: 51.5
#> Geodetic CRS: WGS 84
#> # A tibble: 4 x 3
#> id set geometry
#> * <int> <chr> <POINT [°]>
#> 1 1 1 (74 40.71)
#> 2 1 2 (0.127 51.5)
#> 3 2 1 (122.4 37.77)
#> 4 2 2 (2.352 48.85)
# get low resolution world map
world <- rnaturalearth::ne_countries(returnclass = "sf") %>%
dplyr::select(name) %>% # keep only country name
sf::st_transform(crs = 4326) %>%
st_make_valid() # useful as of 1.0 `sf` update, see https://github.com/r-spatial/sf/issues/1649
# join columns, if you want a country only if the point is within its borders
within_sf <- sf::st_join(x = coords_sf,
y = world,
join = sf::st_within)
within_sf
#> Simple feature collection with 4 features and 3 fields
#> Geometry type: POINT
#> Dimension: XY
#> Bounding box: xmin: 0.127 ymin: 37.77 xmax: 122.4 ymax: 51.5
#> Geodetic CRS: WGS 84
#> # A tibble: 4 x 4
#> id set geometry name
#> * <int> <chr> <POINT [°]> <chr>
#> 1 1 1 (74 40.71) Kyrgyzstan
#> 2 1 2 (0.127 51.5) United Kingdom
#> 3 2 1 (122.4 37.77) <NA>
#> 4 2 2 (2.352 48.85) France
# join columns, if you want the country closest to the point
# (even if the point is not within the border of any country)
nearest_sf <- sf::st_join(x = coords_sf,
y = world,
join = sf::st_nearest_feature)
nearest_sf
#> Simple feature collection with 4 features and 3 fields
#> Geometry type: POINT
#> Dimension: XY
#> Bounding box: xmin: 0.127 ymin: 37.77 xmax: 122.4 ymax: 51.5
#> Geodetic CRS: WGS 84
#> # A tibble: 4 x 4
#> id set geometry name
#> * <int> <chr> <POINT [°]> <chr>
#> 1 1 1 (74 40.71) Kyrgyzstan
#> 2 1 2 (0.127 51.5) United Kingdom
#> 3 2 1 (122.4 37.77) China
#> 4 2 2 (2.352 48.85) France
# now you have a country for each point.
# time to go back to your original format
# again a data frame, not any more an sf object
nearest_df <- dplyr::bind_cols(nearest_sf %>%
sf::st_drop_geometry(),
nearest_sf %>%
sf::st_coordinates() %>%
tibble::as_tibble() %>%
dplyr::rename(lon = X, lat = Y))
nearest_df
#> # A tibble: 4 x 5
#> id set name lon lat
#> <int> <chr> <chr> <dbl> <dbl>
#> 1 1 1 Kyrgyzstan 74 40.7
#> 2 1 2 United Kingdom 0.127 51.5
#> 3 2 1 China 122. 37.8
#> 4 2 2 France 2.35 48.8
output_df <- dplyr::bind_cols(nearest_df %>%
dplyr::filter(set == 1) %>%
dplyr::transmute(lat_1 = lat, lon_1 = lon, name_1 = name),
nearest_df %>%
dplyr::filter(set == 2) %>%
dplyr::transmute(lat_2 = lat, lon_2 = lon, name_2 = name))
output_df
#> # A tibble: 2 x 6
#> lat_1 lon_1 name_1 lat_2 lon_2 name_2
#> <dbl> <dbl> <chr> <dbl> <dbl> <chr>
#> 1 40.7 74 Kyrgyzstan 51.5 0.127 United Kingdom
#> 2 37.8 122. China 48.8 2.35 France
由 reprex package (v2.0.0)
于 2021-06-18 创建作为参考,我也会在这里留下一个 link 到基于 shiny 的解决方案: https::github.com/giocomai/latlon2map / here's an hosted version if you want to have a quick look: latlon2map.europeandatajournalism.eu。有了这个,你可以加载你的 csv,select 你的第一组经纬度,下载 table,用另一组再做一次,并将结果合并到 R 或其他地方。
上面的部分代码改编自同一包的ll_match()
函数。