title: Calculate the length of shared boundaries between multiple polygons
body: <p>I have a shapefile and I want to know for each polygon what other polygons touch it. To that end I have this code:</p>
  
  <pre><code>require("rgdal")  
  require("rgeos")
  
  download.file("https://www.dropbox.com/s/vbxx9dic34qwz63/Polygons.zip?dl=1", "Polygons.zip")
  
  Shapefile &lt;- readOGR(".","Polygons")
  
  Touching_List &lt;- gTouches(Shapefile, byid = TRUE, returnDense=FALSE)
  
  Touching_DF &lt;- setNames(stack(lapply(Touching_List, as.character)), c("TOUCHING", "ORIGIN"))
  </code></pre>
  
  <p>I now want to go further and understand the extent to which each polygon touch other polygons. What I am after for each row in <code>Touching_DF</code> is a total length/perimeter for each <code>ORIGIN</code> polygon and the total length that each <code>TOUCHING</code> polygon is touching the origin polygon. This will then allow the percentage of the shared boundary to be calculated. I can imagine the output of this would be 3 new columns in <code>Touching_DF</code> (e.g. for the first row it could be something like origin parameter 1000m, touching length 500m, shared boundary 50%). Thanks.</p>
  
  <p><strong>EDIT 1</strong></p>
  
  <p>I have applied @StatnMap's answer to my real dataset. It appears that <code>gTouches</code> is returning results if a polygon shares both an edge and a point. These points are causing issues because they have no length. I have modified StatnMap's portion of code to deal with it, but when it comes to creating the data frame at the end there is a mismatch between how many shared edges/vertices gTouches returns and how many edges have lengths. </p>
  
  <p>Here is some code to demonstrate the problem using a sample of my actual dataset:</p>
  
  <pre><code>library(rgdal)  
  library(rgeos)
  library(sp)
  library(raster)
  
  download.file("https://www.dropbox.com/s/hsnrdfthut6klqn/Sample.zip?dl=1", "Sample.zip")
  
  unzip("Sample.zip")
  Shapefile &lt;- readOGR(".","Sample")
  
  Touching_List &lt;- gTouches(Shapefile, byid = TRUE, returnDense=FALSE)
  
  # ---- Calculate perimeters of all polygons ----
  perimeters &lt;- sp::SpatialLinesLengths(as(Shapefile, "SpatialLines"))
  
  # ---- All in a lapply loop ----
  all.length.list &lt;- lapply(1:length(Touching_List), function(from) {
    lines &lt;- rgeos::gIntersection(Shapefile[from,], Shapefile[Touching_List[[from]],], byid = TRUE)
    if(class(lines) != "SpatialLines"){lines &lt;- lines@lineobj}
    l_lines &lt;- sp::SpatialLinesLengths(lines, longlat=FALSE)
    results &lt;- data.frame(origin = from,
                      perimeter = perimeters[from],
                      touching = Touching_List[[from]],
                      t.length = l_lines,
                      t.pc = 100*l_lines/perimeters[from])
    results
  })
  </code></pre>
  
  <p>This specifically shows the issue for one of the polygons:</p>
  
  <pre><code>from &lt;- 4
  lines &lt;- rgeos::gIntersection(Shapefile[from,], Shapefile[Touching_List[[from]],], byid = TRUE)
  if(class(lines) != "SpatialLines"){lines &lt;- lines@lineobj}
  l_lines &lt;- sp::SpatialLinesLengths(lines, longlat=FALSE)
  
  plot(Shapefile[c(from, Touching_List[[from]]),])
  plot(lines, add = TRUE, col = 1 + 1:length(Touching_List[[from]]), lwd = 2)
  </code></pre>
  
  <p>The two possible solutions I see are 1. getting gTouches to return only shared edges with a length greater than zero or 2. returning a length of zero (rather than error) when a point rather than an edge is encountered. So far I can't find anything that will do either of these things.</p>
  
  <p><strong>EDIT 2</strong></p>
  
  <p>@StatnMap's revised solution works great. However, if a polygon does not share a snapped boarder with its neighbouring polygon (i.e. it goes to a point and then creates an island slither polygon) then it comes up with this error after <code>lines &lt;- rgeos::gIntersection(Shapefile[from,], Shapefile[Touching_List[[from]],], byid = TRUE)</code></p>
  
  <pre><code>   Error in RGEOSBinTopoFunc(spgeom1, spgeom2, byid, id, drop_lower_td, unaryUnion_if_byid_false,  : 
        Geometry collections may not contain other geometry collections
  </code></pre>
  
  <p>I have been looking for a solution that is able to identify polygons with badly drawn borders and not perform any calculations and return 'NA' in <code>res</code> (so they can still be identified later). However, I have been unable to find a command that distinguishes these problematic polygons from 'normal' polygons. </p>
  
  <p>Running @StatnMap's revised solution with these 8 polygons demonstrates the issue:</p>
  
  <pre><code>download.file("https://www.dropbox.com/s/ttg2mi2nq1gbbrq/Bad_Polygon.zip?dl=1", "Bad_Polygon.zip")
  unzip("Bad_Polygon.zip")
  Shapefile &lt;- readOGR(".","Bad_Polygon")
  </code></pre>