how to extract lng and lat from tibble?

I would like to get a new dataframe or tibble containing:
ADMIN, ISO_A3,
and lng and lat from the geometry column.

library(tidyverse)
library(sf)
dt <- tibble::tribble(~from, ~to,
                      "Western Sahara", "Morocco",
                      "Somaliland", "Somalia", 
                      "Baykonur Cosmodrome", "Kazakhstan")

dataset <- sf::read_sf("https://github.com/CodingWith-Adam/geoJson-map-with-react-leaflet/raw/master/src/data/countries.json")

for (i in 1:nrow(dt)){
  dataset$geometry[dataset$ADMIN == dt$to[i]] <-
    dataset$geometry[dataset$ADMIN %in% c(dt$to[i], dt$from[i])] %>% 
    sf::st_union() %>% 
    sf::st_collection_extract("POLYGON") %>% 
    sfheaders::sf_remove_holes()
}

# Drop Countries
dataset <- dataset[!dataset$ADMIN %in% c(dt$from), ]

Your dataset object contains 252 multipolygons with quite complex boundaries.

Are you after a list of lat and long values of all the points defining the multipolygons, or are you after a single latitude and longitude per country? eg. a centroid or what not?

You may want to clarify this part, as the technique used will differ.

I would like to have list of lat and long values of all points to use in ggplot2 similar to map_data('world')
Also if you provide how to get a single latitude and longitude per country (would be perfect in case in the future).

Well... the technique of plotting maps using a list of lat and long values is somewhat dated, I wouldn't call it current best practice. But it does work.

What you need to do is convert from sf package format (the current best practice) to sp package format, and then call ggplot2::fortify() on the result.


old_style <- as(dataset, "Spatial") %>% 
  fortify()


ggplot(old_style, aes(x = long, y = lat, group = group)) +
  geom_polygon()

This would be code from like 2018 or so - no longer the bestest of best practice, but it does work.

What I would suggest instead is to leave your dataset in sf package format and use the ggplot2::geom_sf() function to plot it like thus:

ggplot() +
  geom_sf(data = dataset)

There will be a number of advantages if you stick to sf (there are reasons why it replaced the older style).

The reason of using the geom_polygon() is i want to replicate the example shown in the Mapping oil production by country in R - Sharp Sight to understand how to use the function.

Oki, then as("Spatial") and fortify is the way for you to go. Just keep in mind that the example you linked - as neat & inspiring as it is - dates from 2017 and the world has moved on since then.

What is the best way to save the modified dataset into a file for a later use? ie write and read functions???

the old method

old_style <- as(dataset, "Spatial") %>% 
  fortify()

drops the other columns of ADMIN and ISO... how to solve this problem ?????

I am afraid you can't - using current package versions that is.

The canonical version would be

old_style <- as(dataset, "Spatial") %>% 
  fortify(region = c("ADMIN", "ISO_A3"))

but it doesn't work anymore, returning

Error:
! `fortify(<SpatialPolygonsDataFrame>, region = ...)` is defunct' was deprecated in ggplot2 3.4.4 and is now defunct.
ℹ Please migrate to sf.

So the solution could be either to downgrade your ggplot2 installation to something lower than 3.4.4 (current version is 3.5.1) or migrate to sf, as the error message not so gently prods you - which would be also my suggestion.

As for serializing a R object to disk consider base::saveRDS() and its base::readRDS() partner.

i have tried this code

temp <- dataset %>% 
  sf::as_Spatial(.)
temp <- merge(ggplot2::fortify(temp), as.data.frame(temp), by.x = "id", by.y = 0)

is this a right way to get coordinates along with other columns???

You really should consider moving to sf - it is the current best practice. There is a reason why the fortify method for sp was deprecated and is now defunct.

You might be able to recreate the object, but it will be somewhat of a software archeology exercise. Using geom_polygon as a mapping tool in a new piece of code is kind of anachronism; let it enjoy its well earned rest...

You will be much better served by geom_sf() with a polygon type sf data frame in data position - and the rest of the example ggplot code, like color scales and annotations and what not, can remain with only minor tweaking.

I am certain you will find the "new" style sf objects easier to manipulate than the old style sp ones; I remember how excited I was when it came out; it made difficult things seem easy and was a game changer in spatial data processing.

2 Likes