How to stop writeOGR from abbreviating Field Names when using "ESRI Shapefile" driver

You can't, it's a shapefile issue. See http://gdal.org/drv_shapefile.html under 'Creation Options'


Your 'ENGL_NAME' shouldn't be abbreviated at all (less than 10 characters), but writeOGR has its own will, it seems.

Instead of

writeOGR(shp, "PolygonsV2", speciesname, driver="ESRI Shapefile")

you might try

library(maptools)
currdir <- getwd() #store your current working directory
setwd(paste(currdir,"PolygonsV2",sep="/")) #switch to your desired folder

writeSpatialShape(shp, speciesname) # write shapefile

setwd(currdir) #switch back to parent folder

As writeSpatialShape seems not have a parameter for the destination, I found this workaround switching the working directory back and forth.

The other problem there is, that it does't produce a .prj-file, but thats a minor problem, compared to destroyed field names.

Waiting for the times when +*#-!(/ ESRI Shapefile format is finally dead and replaced by ... well?


I've been having similar troubles working in RStudio. Per the advice in various comments and answers above, my scorched-earth solution is:

  • at the point where the SpatialWhateverDataFrame is ready to be written to Shape, make a copy
  • names(copy@data) <- c('new', 'short', 'names', 'you', 'pickd', 'yrslf')
  • names(copy@data) <- strtrim(names(copy@data), 10) just to be sure
  • writeOGR(copy, dsn, layer, driver = 'ESRI Shapefile') but don't run it yet
  • save the script, clear the workspace including hidden objects, restart R, rerun the entire script.

writeOGR() uses base::abbreviate - here's a test with a copy of lines 158-164:

fld_names <- c('short', 'longlonglong', 'middle_1')
if (any(nchar(fld_names) > 10)) {
    fld_names <- abbreviate(fld_names, minlength = 7)
    warning("Field names abbreviated for ESRI Shapefile driver")
    if (any(nchar(fld_names) > 10)) 
      fld_names <- abbreviate(fld_names, minlength = 5)
  }

> fld_names
       short longlonglong     middle_1 
     "short"    "lnglngl"    "middl_1" 
> names(fld_names)
[1] "short"        "longlonglong" "middle_1"  

You can see it actually calls abbreviate twice (possibly pointlessly, I can't figure out how you'd trigger that sub-loop), and if even one column name > 10 then it'll shorten any column name with > 7 characters. I cant figure out why one has to clear the workspace and restart if writeOGR has been run on the same object before, but maybe its something to do with fld_names being a named character vector. It might work better if as.character() was wrapped around abbreviate().