See here a complete reprex of how to achieve that. The steps are:
- Get the data and make it valid with
st_make_valid
(needed if you use sf (>= 1.0.0)
- Create a slim and long polygon where the polygons would break given your desired longitude.
- Remove the created polygon from your shape. This would effectively "break" the polygon on the right place (I.e. on the new limits of the map after projecting it).
- Transform to your desired projection and map.
See full reprex here:
# Load libraries
library(ggplot2)
theme_set(theme_bw())
library(sf)
#> Linking to GEOS 3.9.0, GDAL 3.2.1, PROJ 7.2.1
library(rnaturalearth)
library(rnaturalearthdata)
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
# Set target crs
target_crs <- st_crs("+proj=cea +lon_0=130 +x_0=0 +y_0=0 +lat_ts=45 +ellps=WGS84 +datum=WGS84 +units=m +no_defs")
# Get data and transform to lon/lat 4326
world <- ne_countries(scale = "medium", returnclass = "sf") %>%
st_transform(4326) %>%
st_make_valid()
# define a long & slim polygon that overlaps the meridian line & set its CRS to match
# that of world
# Centered in lon 130 on this example
offset <- 180 - 130
polygon <- st_polygon(x = list(rbind(
c(-0.0001 - offset, 90),
c(0 - offset, 90),
c(0 - offset, -90),
c(-0.0001 - offset, -90),
c(-0.0001 - offset, 90)
))) %>%
st_sfc() %>%
st_set_crs(4326)
# Remove slim polygon
world_fixed <- world %>% st_difference(polygon)
#> Warning: attribute variables are assumed to be spatially constant throughout all
#> geometries
# Transform to desired projection
world_fixed <- st_transform(world_fixed, target_crs)
# Plot - no need ggplot2::coord_sf()
ggplot(data = world_fixed) +
geom_sf()

sessionInfo()
#> R version 4.1.0 (2021-05-18)
#> Platform: x86_64-w64-mingw32/x64 (64-bit)
#> Running under: Windows 10 x64 (build 19042)
#>
#> Matrix products: default
#>
#> locale:
#> [1] LC_COLLATE=Spanish_Spain.1252 LC_CTYPE=Spanish_Spain.1252
#> [3] LC_MONETARY=Spanish_Spain.1252 LC_NUMERIC=C
#> [5] LC_TIME=Spanish_Spain.1252
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] dplyr_1.0.7 rnaturalearthdata_0.1.0 rnaturalearth_0.1.0
#> [4] sf_1.0-1 ggplot2_3.3.5
#>
#> loaded via a namespace (and not attached):
#> [1] Rcpp_1.0.7 pillar_1.6.1 compiler_4.1.0 highr_0.9
#> [5] class_7.3-19 tools_4.1.0 digest_0.6.27 lattice_0.20-44
#> [9] evaluate_0.14 lifecycle_1.0.0 tibble_3.1.3 gtable_0.3.0
#> [13] pkgconfig_2.0.3 rlang_0.4.11 reprex_2.0.0 DBI_1.1.1
#> [17] yaml_2.2.1 xfun_0.24 e1071_1.7-7 s2_1.0.6
#> [21] withr_2.4.2 styler_1.5.1 stringr_1.4.0 knitr_1.33
#> [25] rgeos_0.5-5 generics_0.1.0 fs_1.5.0 vctrs_0.3.8
#> [29] classInt_0.4-3 grid_4.1.0 tidyselect_1.1.1 glue_1.4.2
#> [33] R6_2.5.0 fansi_0.5.0 rmarkdown_2.9 sp_1.4-5
#> [37] purrr_0.3.4 magrittr_2.0.1 units_0.7-2 backports_1.2.1
#> [41] scales_1.1.1 ellipsis_0.3.2 htmltools_0.5.1.1 assertthat_0.2.1
#> [45] colorspace_2.0-2 KernSmooth_2.23-20 utf8_1.2.2 proxy_0.4-26
#> [49] stringi_1.7.3 wk_0.5.0 munsell_0.5.0 crayon_1.4.1
Created on 2021-07-27 by the reprex package (v2.0.0)