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?
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()