I have this piece of code that want to turn into a function

r <- readShapeSpatial("roads")
b <- readShapeSpatial("buildings")
lc <- readShapeSpatial("landcover.shp")

here is the preparation

laer <- function(x,y,z) {
  r <- readShapeSpatial(x)
  b <- readShapeSpatial(y)
  lc <- readShapeSpatial(z)

Then i use the function that i just created

laer("railways.shp","buildings.shp","natural.shp ")

and i get this

Error in getinfo.shape(filen) : Error opening SHP file

the working directory is in check and i also tried putting it inside the script to no avail.


I would suggest reading and plotting the data separately. Since you are likely reading different feature classes (points, lines, polys) it will be difficult to define the plotting symbology in a function. However, given your question here is an example that illustrates translating your workflow into a function. The example function does not limit the arguments to three options, but rather allows a vector of n length defining the shapefile names that you want to import. The plot function is optional (TRUE/FALSE) and the function results in a list object, containing the imported shapefiles, with sp class objects representing the featureclass type of the source.

# Import, and optionally plot, shapefiles
## Parameters
# x = a vcector of shapefile names, without ".shp" extension 
# plot  (TRUE/FALSE) should imported sp objects be plotted, sequentially. 
## Returns
# a list object containing sp class objects     
shp.import <- function(x, plot = TRUE) {
      # check for rgdal package
      if(!"rgdal" %in% installed.packages()) 
        stop("rgdal package does not exist")

      # Use lapply to iteratively add shapefiles listed in "x" variable, add names to list 
      x.shp <- lapply(as.list(x), function(s) rgdal::readOGR(getwd(), s) )
        names(x.shp) <- x

      # Plot each sp object in list
      if( plot == TRUE ) {
        lapply(x.shp[-1], function(p) plot(p, add=TRUE) )
      return( x.shp )

# Now, lest run it
# Add library and set working directory containing shapefiles

# Character vector of shapefile names to import
shp <- c("roads", "buildings", "landcover")

# Run function
s <- shp.import(shp)

# Check class of "s" and contents of "s" object

# Plot specific object in list

In this function I am using a list object for the convenience of using lapply for plotting purposes. The returned list contains the imported shapefiles. Alternately, you could use assign to create separate objects. assign(i, rgdal::readOGR(getwd(), i))

  • seems pretty neat,but i have some questions, what is the "s"? – gsa Apr 25 '15 at 17:51
  • s is the list object containing the imported shapefiles. If you look at the results of the two class statements you will notice that the class of "s" is a list and s[[1]] is a spatial class object. Think of "s" as a container with your spatial objects. An object can be extracted to a new object using an assignment eg., lc <- s[[3]] or lc <- s[["landcover"]] – Jeffrey Evans Apr 25 '15 at 17:55
  • i am talking about the function(s) part, u haven't given any value to that and i dont get it. – gsa Apr 25 '15 at 18:08
  • lapply expects a function to apply over the list object. I am defining the function directly in lapply, where; "s" is the functions argument that is passed to readOGR and represents in index of each element in the list, in this case a list of shapefile names. Latter, for plotting, the index is p. Please take a look at the help for lapply. I should note that I am using rgdal to read shapefiles and not maptools. – Jeffrey Evans Apr 25 '15 at 20:24
  • And where is the part that the user sets his shps.in the libray(sp) and below? Can u please, insert more comments in the most trickiest according to a novice in R parts? – gsa Apr 26 '15 at 9:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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