Search code examples
rgisshapefiler-sf

How to use the function read_sf() in the sf package to read a shape file when it works in QGIS in R


I have a shape file called gadm41_EGY_1.shp, which I have successfully been using to do analysis in QGIS, and I want to read it into R using the function read_sf() in the sf package.

I want to do a pseudo-absence analysis in R, and I need to read the shape file and visually plot the map in the plotting environment in R Studio.

In order to ensure that the direct path to the shape file is correct, I set my work directory manually to ensure the pathway is correct.

Does anyone know what I'm doing wrong?

  1. First attempt:

    #Install the pacakge sf
    install.packages("sf", configure.args = "--with-proj-lib=/usr/local/lib/")
    
    library(sf)
    
    #Set the CRS
    crswgs84=CRS("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs")
    
    #Plot the shape file 
    Egypt_Sf<-read_sf("/Users/Documents/gadm41_EGY_1_Shape/gadm41_EGY_1.shp", 
                        proj4string=crswgs84, verbose=TRUE)
    

    Error message:

    Error: Cannot open "/Users/Documents/gadm41_EGY_1_Shape/gadm41_EGY_1.shp""; The source could be corrupt or not supported. See `st_drivers()` for a list of supported formats.
    In addition: Warning message:
    In CPL_read_ogr(dsn, layer, query, as.character(options), quiet,  :
      GDAL Error 4: Unable to open /Users/Documents/gadm41_EGY_1_Shape/gadm41_EGY_1.shp" or /Users/Documents/gadm41_EGY_1_Shape/gadm41_EGY_1.shp".SHX. Set SHAPE_RESTORE_SHX config option to YES to restore or create it.
    
  2. Second attempt:

    #Define a path to the shapefile 
    Ds_sf <- system.file("/Users/Documents/gadm41_EGY_1_Shape/gadm41_EGY_1.shp")
    Ds_sf
    
    #Set the CRS
    crswgs84=CRS("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs")
    
    #Read shape file in R
    Egypt_Sf<-read_sf(Ds_sf, proj4string=crswgs84, quiet = TRUE, verbose=TRUE)
    

    Error message:

    Error: `dsn` must point to a source, not an empty string.
    
  3. Third attempt:

    Egypt_Sf <- read_sf(dsn = "/Users/Documents/gadm41_EGY_1_Shape/gadm41_EGY_1.shp", 
                             quiet=TRUE, verbose=TRUE, stringAsFactors=TRUE)
    

Error message:

Error in st_sf(x, ..., agr = agr, sf_column_name = sf_column_name) : 
  no simple features geometry column present

Solution

  • You seem to be dealing with Shapefiles from https://gadm.org/data.html . As we really don't know how are you handling those downloads & files, it's probably easier to start with a clean copy.

    When saving Shapefile archive as a .shp.zip, sf / GDAL can guess that it's a zipped ESRI shapefile, it might include multiple datasets (as in case of GADM datasets) and those can be handled as layers:

    library(sf)
    #> Linking to GEOS 3.12.1, GDAL 3.8.4, PROJ 9.3.1; sf_use_s2() is TRUE
    
    gadm_egy_url <- "https://geodata.ucdavis.edu/gadm/gadm4.1/shp/gadm41_EGY_shp.zip"
    
    # download, save as .shp.zip
    download.file(gadm_egy_url, "gadm41_EGY.shp.zip")
    
    # list layers (individual shp files in the archive)
    st_layers("gadm41_EGY.shp.zip")
    #> Driver: ESRI Shapefile 
    #> Available layers:
    #>     layer_name geometry_type features fields crs_name
    #> 1 gadm41_EGY_0       Polygon        1      2   WGS 84
    #> 2 gadm41_EGY_1       Polygon       27     11   WGS 84
    #> 3 gadm41_EGY_2       Polygon      343     13   WGS 84
    
    # load one 
    read_sf("gadm41_EGY.shp.zip", layer = "gadm41_EGY_1")
    #> Simple feature collection with 27 features and 11 fields
    #> Geometry type: MULTIPOLYGON
    #> Dimension:     XY
    #> Bounding box:  xmin: 24.6981 ymin: 21.72539 xmax: 36.24875 ymax: 31.66792
    #> Geodetic CRS:  WGS 84
    #> # A tibble: 27 × 12
    #>    GID_1  GID_0 COUNTRY NAME_1 VARNAME_1 NL_NAME_1 TYPE_1 ENGTYPE_1 CC_1  HASC_1
    #>    <chr>  <chr> <chr>   <chr>  <chr>     <chr>     <chr>  <chr>     <chr> <chr> 
    #>  1 EGY.1… EGY   Egypt   Ad Da… Al Daqah… الدقهلية  Muhaf… Governor… NA    EG.DQ 
    #>  2 EGY.2… EGY   Egypt   Al Ba… Mar Rojo… محافظة ا… Muhaf… Governor… NA    EG.BA 
    #>  3 EGY.3… EGY   Egypt   Al Bu… Beheira|… البحيرة   Muhaf… Governor… NA    EG.BH 
    #>  ...
    

    With sf we can also use GDAL Virtual Filesystems, e.g. define that we are dealing with an URL of a zip-file and let GDAL handle downloading and extracting:

    read_sf(paste0("/vsizip/vsicurl/", gadm_egy_url, "/gadm41_EGY_1.shp"))
    #> Simple feature collection with 27 features and 11 fields
    #> Geometry type: MULTIPOLYGON
    #> ... 
    

    Or just use geodata pacakge to download GADM datasets:

    geodata::gadm("Egypt", path = "./") |> 
      st_as_sf()
    #> Simple feature collection with 27 features and 11 fields
    #> Geometry type: GEOMETRY
    #> ...
    
    

    Created on 2024-10-05 with reprex v2.1.1