75

I need to open a shapefile from ArcMap in R to use it for further geostatistical analysis. I've converted it into ASCII text file, but in R it is recognized as data.frame. Coordinates function doesn't work as soon as x and y are recognized as non-numeric.

Could you help to deal with it?

1
  • 1
    What kind of shapefile? I'm assuming points since it has an X and Y column?
    – Simbamangu
    Commented Jan 20, 2012 at 11:41

6 Answers 6

67

Use the shapefile directly. You can do this easily with the rgdal or sf packages, and read the shape in an object. For both packages you need to provide dsn - the data source, which in the case of a shapefile is the directory, and layer - which is the shapefile name, minus extension:

# Read SHAPEFILE.shp from the current working directory (".")

require(rgdal)
shape <- readOGR(dsn = ".", layer = "SHAPEFILE")

require(sf)
shape <- read_sf(dsn = ".", layer = "SHAPEFILE")

You can replace "." with a full directory location such as "C:/USERS/Downloads/" or "/home/user/Downloads/".

(For rgdal, in OSX or Linux you can't use the '~' shorthand for the home directory as the data source (dsn) directory - otherwise you'll get an unhelpful "Cannot open data source" message. The sf package doesn't have this limitation, among some other advantages.)

This will give you an object which is a Spatial*DataFrame (points, lines or polygons) - the fields of the attribute table are then accessible to you in the same way as an ordinary dataframe, i.e. shape$ID for the ID column.

If you want to use the ASCII file you imported, then you should simply convert the text (character) x and y fields to numbers, e.g.:

shape$x <- as.numeric(as.character(shape$x))
shape$y <- as.numeric(as.character(shape$y))
coordinates(shape) <- ~x + y

Edit 2015-01-18: note that rgdal is a bit better than maptools (which I initially suggested here), primarily because it reads and writes projection information automatically.

Notes:

  • the nested as.numeric(as.character()) functions - if your ASCII text was read as a factor (likely), this ensures that you get the numeric values instead of the factor levels.
  • rgdal and sf have confusing ways of accessing different file and database types (e.g. for a GPX file, the dsn is the filename, and layers the individual components such as waypoints, trackpoints, etc), and careful reading of online examples is needed.

Examples with sf

Shapefile with myshape.shp, myshape.shx, myshape.dbf etc in working dir:

read_sf(dsn = ".", layer = "myshape")

Geopackage with mypkg.gpkg containing 'polylayer' in working dir:

read_sf(dsn = "mypkg.gpkg", layer = 'polylayer')
5
  • R should parse numeric fields so, I would imagine that there is a special character type in x and y. In addition, on import, unless specified differently, character fields will be coerced into a factor. As such, a simple "as.numeric" deceleration will not work. I would also use "readORG" in "rgdal" rather than maptools. Commented Jan 16, 2015 at 18:37
  • @Jeffrey, readOGR is definitely the better way to go - see some discussions on later R questions here on gis.SE. Good point on factor coercion; will update with nested as.character to get around the problem.
    – Simbamangu
    Commented Jan 18, 2015 at 9:04
  • You could use ~, but you'd have to call path.expand on the directory, e.g. readOGR(dsn=path.expand("~/Downloads/cb_2016_us_zcta510_500k/"), layer="cb_2016_us_zcta510_500k")
    – hd1
    Commented Nov 20, 2017 at 0:51
  • 3
    Somehow I still needed a clarification this actually correct answer: dsn="directory where the shapefile, projection file, etc are located" layer="name of the file without .shp extention"
    – Ufos
    Commented Apr 19, 2018 at 8:44
  • I want to note that the dsn argument should not contain trailing slashes---e.g. dsn = "C:/Users/Downloads/" should be dsn = "C:/Users/Downloads". Hope this solves someone's frustration...
    – Kim
    Commented Apr 24, 2019 at 22:26
29

You can use sf library to open Shapefiles directly in R. It's faster than rgdal library, check here: Simple Features for R - Benchmarks. For further information about the sf package check the project homepage r-spatial.

# Load library
library('sf')

# Load shapefile
shapename <- read_sf('~/path/to/file.shp')
21

I agree with the Simbamangu and gissolved in terms of retaining the shapefile but want to direct your attention specifically to the rgdal library. Follow the link suggested by gissolved for the NCEAS and follow through with the directions for rgdal. It can be challenging to install on some machines but it can substantially improve results when it comes to projections.

The maptools library is excellent and allows you to define the projection for the shapefile you are reading in, but to do so you need to know how to specify that projection in the proj4 format. an example might look something like:

project2<-"+proj=eqdc +lat_0=0 +lon_0=0 +lat_1=33 +lat_2=45 +x_0=0 +y_0=0 +ellps=GRS80    
   +datum=NAD83 +units=m +no_defs" #USA Contiguous Equidistant Conic Projection
data.shape<-readShapePoly("./MyMap.shp",IDvar="FIPS",proj4string=CRS(project2))
plot(data.shape)

If you want to go this route, then I recommend http://spatialreference.org as the place to go to figure out what your projection looks like in the proj4 format. If that looks like a hassle to you, rgdal will make it easy by reading the ESRI shapefile's .prj file (the file that contains ESRI's projection definition for the shapefile. To use rgdal on the same file you would simply write:

library(rgdal)
data.shape<-readOGR(dsn="C:/Directory_Containing_Shapefile",layer="MyMap")
plot(data.shape)

You can likely skate by without doing this if you are just working with a single shapefile, but as soon as you start looking at multiple data sources or overlaying with Google Maps, keeping your projections in good shape becomes essential.

For some helpful walkthroughs on spatial data in R, including a bunch of stuff on importing and working with point patterns, I have some old course materials online at https://csde.washington.edu/workshop/point-patterns-and-raster-surfaces/ (more workshops can be found here) that might help you see how these methods compare in practice.

3
  • +1 for spatial reference information ... especially for emphasizing keeping projections sorted out!
    – Simbamangu
    Commented Jan 23, 2012 at 14:34
  • @csfowler, I tried to use the readOGR but it is not importing the .prj file. Any idea why? I am at UW as well, in the biology department. Commented Oct 13, 2013 at 6:49
  • @user4050, hard to know without seeing your code. I assume there is a .prj file in the same directory? and that you used the encoding = "ESRI Shapefile" value to make sure rgdal knows it is a shapefile?
    – csfowler
    Commented Oct 31, 2013 at 15:48
17

I think you shouldn't convert the shapefile to an ASCII but instead use the shapefile directly with one of the spatial extensions. Here you can find a three ways to read (and write) a shapefile http://www.nceas.ucsb.edu/scicomp/usecases/ReadWriteESRIShapeFiles. The R-spatial project will probably also interest you http://cran.r-project.org/web/packages/sp/index.html.

17

An easy solution in 2017 is the shapefile() function in the raster library. Actually,as the help file says, is a "simple wrapper function around readOGR and writeOGR (rgdal package)"

#Load library
library(raster)

#Load shapefile
shp <- shapefile("myshapefile.shp")

2024 UPDATE: The raster library has been replaced by the terra library. You can now use the terra::vect function to open a shapefile, which will create a SpatVector object.

#Load library
library(terra)

#Load shapefile
shp <- vect("myshapefile.shp")

You can also use sf::st_read(), which will create an sf object.

#Load library
library(sf)

#Load shapefile
shp <- st_read("myshapefile.shp")
3
  • Can this be used to import from an online source? I
    – I Del Toro
    Commented Feb 26, 2019 at 16:27
  • @IDelToro Not directly. You'll need to download it to your hard drive first and then load it from there. Commented Feb 27, 2019 at 17:08
  • 1
    Update as of 2024. The 'raster' library is being replaced by 'terra' Commented Apr 10 at 5:54
6

One more alternative is to use fastshp library which offers::

Routines for handling of large ESRI shapefiles (.shp). This includes reading, thinning of points and matching of points to containing shapes. The main aim for this package is to provide the speed to support large shapefiles (millions of points). It is several orders of maginute faster than some other shapefile packages.

Here is my question on SE on how to use it with ggplot2:

How can I plot shapefile loaded through fastshp in ggplot2?

1
  • 1
    I find it a bit annoying that the read.shp function does not result in an sp object. Given that the spatial R community is converging on this as the de facto standard for handling spatial objects, I find this somewhat sloppy. Given sufficient RAM and a 64bit OS, reading large data is not much of an issue. With 8GB RAM I have read 30M points and 2.5M polygons using rgdal with no issues. Here is some direction on using sp objects with ggplot2: github.com/hadley/ggplot2/wiki/plotting-polygon-shapefiles Commented Nov 2, 2012 at 19:47

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.