rggplot2rworldmap

similar output from st_as_sf() and fortify()


I'm trying to get the same output with sf::st_as_sf() that I get with the soon-to-be-deprecated ggplot2::fortify():

library(rworldmap)
library(sf)
library(ggplot2)

world_map <- rworldmap::getMap()

points <- ggplot2::fortify(world_map)

points_2 <- sf::st_as_sf(world_map) 

returns a df with columns "long", "lat", "order", "hole", "piece", "id", and "group", where multiple polygons for a country (=id) and their respective lat-long are a unique row (=group).

      long      lat order  hole piece          id         group
1 61.21082 35.65007     1 FALSE     1 Afghanistan Afghanistan.1
2 62.23065 35.27066     2 FALSE     1 Afghanistan Afghanistan.1
3 62.98466 35.40404     3 FALSE     1 Afghanistan Afghanistan.1
4 63.19354 35.85717     4 FALSE     1 Afghanistan Afghanistan.1

st_as_sf appears to keep the additional polygons in the list-column "geometry". Is there an option for st_as_sf to return the dataframe with the list flattened in the same way fortify does?


Solution

  • fortify is a generic function. The specific method is ggplot2:::fortify.SpatialPolygonsDataFrame which in turn calls other fortify methods for the various components of the map.

    You can create your own little function that does much the same thing:

    my_fortify <- function(map) {
      do.call("rbind",
        lapply(map@polygons, function(x) {
          do.call("rbind",
            lapply(seq_along(x@Polygons), function(i) {
            df <- setNames(as.data.frame(x@Polygons[[i]]@coords), c("long", "lat"))
            df$order <- 1:nrow(df)
            df$hole <- x@Polygons[[i]]@hole
            df$piece <- i
            df$id <- x@ID
            df$group <- paste(x@ID, i, sep = '.')
            df
            }))
        })
      )
    }
    

    So now we have:

    head(my_fortify(world_map))
    #>       long      lat order  hole piece          id         group
    #> 1 61.21082 35.65007     1 FALSE     1 Afghanistan Afghanistan.1
    #> 2 62.23065 35.27066     2 FALSE     1 Afghanistan Afghanistan.1
    #> 3 62.98466 35.40404     3 FALSE     1 Afghanistan Afghanistan.1
    #> 4 63.19354 35.85717     4 FALSE     1 Afghanistan Afghanistan.1
    #> 5 63.98290 36.00796     5 FALSE     1 Afghanistan Afghanistan.1
    #> 6 64.54648 36.31207     6 FALSE     1 Afghanistan Afghanistan.1
    

    and

    ggplot(my_fortify(world_map), aes(long, lat, group = group)) + geom_polygon()
    

    enter image description here