3

I'm trying to use Resolve ecoregion data to map the biomes of the African continent. The shapefile is global, and there are over 800 polygons, as each polygon represents a unique ecological area (whereas there are only seven terrestrial biomes, biomes are the larger spatial unit and are composed of similar ecological areas). Perhaps because of the data size or number of polygons, I am having a difficult time producing a map using tmap.

I first cropped the shapefile to the African continent:

resolve = st_read("Data/Ecoregions2017/Ecoregions2017.shp")

Africa = st_read("Data/Africa_SHP/Africa/Africa.shp")
st_crs(Africa) = crs(resolve)

resolveAfrica =st_intersection(st_make_valid(resolve), st_make_valid(Africa))

But when I try to then map this cropped shapefile:

tm_shape(Africa) + tm_borders() +
  tm_shape(resolveAfrica) + tm_fill("BIOME_NAME")

R returns an error:

Error in vapply(lst, class, rep(NA_character_, 3)) : 
  values must be length 3,
 but FUN(X[[56]]) result is length 2

Does anyone know what steps I can take to address this error?

5
  • Does it work if you subset the data? In other words, can you test your hypothesis that it is the size of the data? It might be one single row of the data, a tiny polygon that you can omit without detriment to your map. Can you tell us the source of your Africa shapefile?
    – Spacedman
    Commented Apr 12, 2021 at 10:06
  • The Africa shapefile is the Esri-provided one. And when I subset the data to one ecological area, I was able to produce a map using tmap.
    – C. Ashley
    Commented Apr 12, 2021 at 22:06
  • This works for me. I used an africa shape derived from continent.zip downloaded from here: baruch.cuny.edu/confluence/display/geoportal/… - using just the "Africa" row. The tmap works perfectly. So either its related to your Africa shape (which might be the same as mine?) or your versions of everything. I'm sf:0.9.6 tmap:3.2 R:4.0.3
    – Spacedman
    Commented Apr 13, 2021 at 10:44
  • I didn't even consider the possibility that the problem was my Africa shapefile (I've been blaming Resolve). Let me download the shapefile here and see if I can produce the map using tmap. Thank you so much for this support!
    – C. Ashley
    Commented Apr 13, 2021 at 15:37
  • I stumbled upon this searching for this same error, but am coincidentally using the resolve ecoregions as well. I think this issue comes up when you have mixed geometry types in the vector file. For instance, in my Resolve subset, one of the geometries is a "GeometryCollection" but tm_fill() only wants polygons/multipolygons. Given these other comments, it looks like perhaps your Africa shapefile has some non-polygons/multipolygons. You might try sf::st_collection_extract(type = "POLYGON") to pull out just the geometries compatible with tm_borders()/tm_fill()/tm_polygons().
    – mikoontz
    Commented Jun 7, 2022 at 15:39

1 Answer 1

1

This error can arise when trying to use a tmap function that expects polygons (like tm_polygons(), tm_fill(), or tm_borders()) on an object that contains GeometryCollection geometries (i.e., a mixture of polygons, lines, points, etc. in the same geometry).

You can use sf::st_geometry_type(Africa) or sf::st_geometry_type(resolveAfrica) to confirm this is the case.

You can use sf::st_collection_extract(Africa, type = "POLYGON") or sf::st_collection_extract(resolveAfrica, type = "POLYGON") to pull out just the polygon geometries from within each of those sf objects, which should then let your tmap function calls work. Even with some of the rows of the object being LINESTRING geometries, tm_fill() and tm_borders() still seems to know what to do with them.

In case that doesn't just work, perhaps you can pull out the individual types of geometries using multiple sf::st_collection_extract() function calls and then rbind() them back together. As an example with the Africa dataset:

Africa_pts <- sf::st_collection_extract(Africa, type = "POINTS")
Africa_lines <- sf::st_collection_extract(Africa, type = "LINES")
Africa_polys <- sf::st_collection_extract(Africa, type = "POLYGONS")

Africa_combined <- rbind(Africa_pts, Africa_lines, Africa_polys)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.