rshapefiler-sftmaptigris

After intersecting two shapefiles: `Error in vapply(g2, st_is_empty, logical(1))`


I run the following:

library(dplyr)
library(sf)
library(tigris)
library(tmap)

options(tigris_class = 'sf')
options(tigris_use_cache = TRUE)

nj = tigris::states(cb = T, year = 2015) %>%
  filter(STUSPS == 'NJ')

nj_msas = tigris::core_based_statistical_areas(cb = T, year = 2015) %>%
  filter(grepl('NJ', NAME)) %>%
  sf::st_intersection(nj)

tmap_mode('plot')

nj_msas %>%
  tm_shape() +
  tm_polygons()

The last chunk gives the error:

Error in vapply(g2, st_is_empty, logical(1)) : values must be length 1, but FUN(X[[3]]) result is length 148

When I remove the st_intersection, I get no error from the last chunk. I can't find this error message anywhere through googling. Does anyone know what's going on?

Also, if I run all of the above except the last chunk, and I use ggplot2::geom_sf to create the map, instead of tmap functions, I get the map I want. No errors.

I'm using Ubuntu 18.04.1. RStudio v1.1.463. R 3.5.2. tigris 0.7. tmap 2.2. sf 0.7-2.


Solution

  • Seems due to the fact that the geometry column resulting from the intersection is of type “GEOMETRY” and not of type “POLYGON”, probably due to slight misalignments between tigris::states and tigris::core_based_statistical_areas, leading to error in tm_shape():

    > nj_msas
    Simple feature collection with 7 features and 17 fields
    geometry type:  GEOMETRY
    dimension:      XY
    bbox:           xmin: -75.55961 ymin: 38.92852 xmax: -73.89398 ymax: 41.35742
    epsg (SRID):    4269
    proj4string:    +proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +no_defs
    CSAFP CBSAFP       AFFGEOID GEOID                                        NAME LSAD       ALAND     AWATER STATEFP
        1   428  36140 310M200US36140 36140                              Ocean City, NJ   M1   651209688  955666476      34
        2   408  10900 310M200US10900 10900           Allentown-Bethlehem-Easton, PA-NJ   M1  3763879943   58581593      34
        3   428  47220 310M200US47220 47220                      Vineland-Bridgeton, NJ   M1  1252937239  502091171      34
        4   408  45940 310M200US45940 45940                                 Trenton, NJ   M1   581629671   11189320      34
        5   428  37980 310M200US37980 37980 Philadelphia-Camden-Wilmington, PA-NJ-DE-MD   M1 11920145588  693341961      34
        6   408  35620 310M200US35620 35620       New York-Newark-Jersey City, NY-NJ-PA   M1 21478408908 6689374328      34
        7   428  12100 310M200US12100 12100                 Atlantic City-Hammonton, NJ   M1  1439256827  300767732      34
           STATENS  AFFGEOID.1 GEOID.1 STUSPS     NAME.1 LSAD.1     ALAND.1   AWATER.1                       geometry
        1 01779795 0400000US34      34     NJ New Jersey     00 19048075783 3543447118 MULTIPOLYGON (((-74.55255 3...
        2 01779795 0400000US34      34     NJ New Jersey     00 19048075783 3543447118 POLYGON ((-75.12051 40.9683...
        3 01779795 0400000US34      34     NJ New Jersey     00 19048075783 3543447118 POLYGON ((-75.41956 39.4132...
        4 01779795 0400000US34      34     NJ New Jersey     00 19048075783 3543447118 POLYGON ((-74.94228 40.3408...
        5 01779795 0400000US34      34     NJ New Jersey     00 19048075783 3543447118 GEOMETRYCOLLECTION (LINESTR...
        6 01779795 0400000US34      34     NJ New Jersey     00 19048075783 3543447118 POLYGON ((-74.02454 40.7094...
        7 01779795 0400000US34      34     NJ New Jersey     00 19048075783 3543447118 POLYGON ((-74.98522 39.5148...
    

    You can solve this by extracting only the polygons from the intersection result:

    library(dplyr)
    library(sf)
    library(tigris)
    library(tmap)
    
    options(tigris_class = 'sf')
    options(tigris_use_cache = TRUE)
    
    nj = tigris::states(cb = T, year = 2015) %>%
      filter(STUSPS == 'NJ')
    
    nj_msas = tigris::core_based_statistical_areas(cb = T, year = 2015) %>%
      filter(grepl('NJ', NAME)) %>%
      sf::st_intersection(nj) %>% 
      sf::st_collection_extract("POLYGON")
    
    tmap_mode('plot')
    #> tmap mode set to plotting
    tm_shape(nj_msas) + tm_polygons()
    

    , or by setting a precision on the nj dataset:

    nj_msas = tigris::core_based_statistical_areas(cb = T, year = 2015) %>%
      filter(grepl('NJ', NAME)) %>%
      sf::st_intersection(sf::st_set_precision(nj ,1000))
    
    tm_shape(nj_msas) + tm_polygons()
    

    Created on 2019-01-10 by the reprex package (v0.2.1)