I'm trying to put concentric circles around a xy location and divide them up into segments for 'ring and sector' analysis. I got it working, reset the environment, ran the code again and it didn't work. I'm stuck at the

#joining points to polys
join <- over (rings,points)
rings@data <- left_join(rings@data, points, by = c("id" = "id"), copy = TRUE)

It says:

"Error in left_join(rings@data, points, by = c(id = "id"), copy = TRUE) : no slot of name "data" for this object of class "SpatialPolygons""

And yes @data does not exist, here's an image of the result when I had it working. Where have I gone wrong? And yes, I will be simplifying the code with for loops when it works.

[![Ring and Sector Analysis][1]][1]

#variables
xcoord <- 50
ycoord <- 50
wd <- 5 #width of rings
rn <-3 #number of rings

#point dataset

#dummy data
set.seed(1)
a <- rnorm(100, mean=50, sd=5)
b <- rnorm(100, mean=50, sd=5)
coords <- cbind(a,b)
points <- SpatialPoints(coords)

#libraries
library(sp)
library(raster)
library(rgdal)
library(rgeos)
library(maptools)

library(dplyr)
library(GISTools)

#create central location
par(mfrow=c(1,1))
xy <- cbind(xcoord,ycoord)
xy <- SpatialPoints(xy)

#make circles
c1 <- gBuffer(xy, width=wd, quadsegs = 10)
c2 <- gBuffer(xy, width=wd*2, quadsegs = 10)
c3 <- gBuffer(xy, width=wd*3, quadsegs = 10)

#make rings
r1 <- c1
r2 <- gDifference(c2,c1)
r3 <- gDifference(c3,c2)

r <- raster::union(r1,r2)
r <- raster::union(r,r3)

#define segments
p1 <- cbind(c(xcoord,xcoord,xcoord+wd*rn,xcoord),
            c(ycoord,ycoord+wd*rn,ycoord+wd*rn,ycoord))
p2 <- cbind(c(xcoord,xcoord+wd*rn,xcoord+wd*rn,xcoord),
            c(ycoord,ycoord+wd*rn,ycoord,ycoord))
p3 <- cbind(c(xcoord,xcoord+wd*rn,xcoord+wd*rn,xcoord),
            c(ycoord,ycoord,ycoord-wd*rn,ycoord))
p4 <- cbind(c(xcoord,xcoord+wd*rn,xcoord,xcoord),
            c(ycoord,ycoord-wd*rn,ycoord-wd*rn,ycoord))
p5 <- cbind(c(xcoord,xcoord,xcoord-wd*rn,xcoord),
            c(ycoord,ycoord-wd*rn,ycoord-wd*rn,ycoord))
p6 <- cbind(c(xcoord,xcoord-wd*rn,xcoord-wd*rn,xcoord),
            c(ycoord,ycoord-wd*rn,ycoord,ycoord))
p7 <- cbind(c(xcoord,xcoord-wd*rn,xcoord-wd*rn,xcoord),
            c(ycoord,ycoord,ycoord+wd*rn,ycoord))
p8 <- cbind(c(xcoord,xcoord-wd*rn,xcoord,xcoord),
            c(ycoord,ycoord+wd*rn,ycoord+wd*rn,ycoord))

p1 <- Polygon(p1)
p2 <- Polygon(p2)
p3 <- Polygon(p3)
p4 <- Polygon(p4)
p5 <- Polygon(p5)
p6 <- Polygon(p6)
p7 <- Polygon(p7)
p8 <- Polygon(p8)

p1 <- Polygons(list(p1),1)
p2 <- Polygons(list(p2),2)
p3 <- Polygons(list(p3),3)
p4 <- Polygons(list(p4),4)
p5 <- Polygons(list(p5),5)
p6 <- Polygons(list(p6),6)
p7 <- Polygons(list(p7),7)
p8 <- Polygons(list(p8),8)

p <- SpatialPolygons(list(p1,p2,p3,p4,p5,p6,p7,p8))

#plot(p[1:6], xlim=c(35,65),ylim=c(35,65))


#plot(r[1], xlim=c(35,65), ylim=c(35,65))
#plot(p[1], add=TRUE)
#plot(r1s1)


#make segments
#ring1
r1s1 <- rgeos::gIntersection(p[1],r[1])
r1s2 <- rgeos::gIntersection(p[2],r[1])
r1s3 <- rgeos::gIntersection(p[3],r[1])
r1s4 <- rgeos::gIntersection(p[4],r[1])
r1s5 <- rgeos::gIntersection(p[5],r[1])
r1s6 <- rgeos::gIntersection(p[6],r[1])
r1s7 <- rgeos::gIntersection(p[7],r[1])
r1s8 <- rgeos::gIntersection(p[8],r[1])

#ring2
r2s1 <- rgeos::gIntersection(p[1],r[2])
r2s2 <- rgeos::gIntersection(p[2],r[2])
r2s3 <- rgeos::gIntersection(p[3],r[2])
r2s4 <- rgeos::gIntersection(p[4],r[2])
r2s5 <- rgeos::gIntersection(p[5],r[2])
r2s6 <- rgeos::gIntersection(p[6],r[2])
r2s7 <- rgeos::gIntersection(p[7],r[2])
r2s8 <- rgeos::gIntersection(p[8],r[2])

#ring3
r3s1 <- rgeos::gIntersection(p[1],r[3])
r3s2 <- rgeos::gIntersection(p[2],r[3])
r3s3 <- rgeos::gIntersection(p[3],r[3])
r3s4 <- rgeos::gIntersection(p[4],r[3])
r3s5 <- rgeos::gIntersection(p[5],r[3])
r3s6 <- rgeos::gIntersection(p[6],r[3])
r3s7 <- rgeos::gIntersection(p[7],r[3])
r3s8 <- rgeos::gIntersection(p[8],r[3])

#plot(r[1:3], xlim=c(35,65), ylim=c(35,65))

#inner ring
s <- r1s1
s <- raster::union(s,r1s2)
s <- raster::union(s,r1s3)
s <- raster::union(s,r1s4)
s <- raster::union(s,r1s5)
s <- raster::union(s,r1s6)
s <- raster::union(s,r1s7)
s <- raster::union(s,r1s8)

#middle ring
s <- raster::union(s,r2s1)
s <- raster::union(s,r2s2)
s <- raster::union(s,r2s3)
s <- raster::union(s,r2s4)
s <- raster::union(s,r2s5)
s <- raster::union(s,r2s6)
s <- raster::union(s,r2s7)
s <- raster::union(s,r2s8)

#outer ring
s <- raster::union(s,r3s1)
s <- raster::union(s,r3s2)
s <- raster::union(s,r3s3)
s <- raster::union(s,r3s4)
s <- raster::union(s,r3s5)
s <- raster::union(s,r3s6)
s <- raster::union(s,r3s7)
s <- raster::union(s,r3s8)

#you can see that the first 8 form in the correct order, 9+ are behaving strangely
plot(s[1:24], xlim=c(35,65), ylim=c(35,65))

plot(p)
plot(s)

rings <- s 


#joining points to polys
join <- over (rings,points)
rings@data <- left_join(rings@data, points, by = c("id" = "id"), copy = TRUE)

plot(rings)
plot(points, add = TRUE)
counts = poly.counts(points,rings)

counts[counts == 0] <- NA

par(mfrow=c(1,2))

shades = auto.shading(counts,cols=brewer.pal(5,'Blues'))
choropleth(rings, counts, shades, xlim=c(35,65),ylim=c(35,65), main="Ring and Sectors")
plot(points, add = TRUE)
  • Were you thinking of doing a spatial join? left_join is just merging two dataframes... Is rather extract(rings, points) what you want? Note in general your code could be extremely simplied! Use lapply for the polygon section, outer for the rgeos::gIntersection section, and Reduce for the union part. – Matifou Nov 15 '16 at 22:38

A few things to fix and it should work:

First, move your libraries to the top of your script or points <- SpatialPoints(coords) errors:

points <- SpatialPoints(coords)
# Error: could not find function "SpatialPoints"

Next, your script as it stands produces rings, but this is a spatialPolygons object, not a spatialPolygonsDataFrame object (i.e. no ...DataFrame) so there is no @data slot to join on.

Instead, you can create a spatialPolygonsDataFrame object using sp::SpatialPolygonsDataFrame:

#joining points to polys
join <- over(rings, points)
rings <- sp::SpatialPolygonsDataFrame(rings, as.data.frame(join), match.ID = FALSE)

Because join is a vector, not a data frame, we must force R to treat is as a one-column data frame with as.data.frame(). Also, this will link records in join and rings in order, not by matching an ID, so make sure the order is correct (or irrelevant).

rings now looks like:

plot of 'rings' object

Finally, but unrelated to this issue, shades errors:

shades = auto.shading(counts,cols=brewer.pal(5,'Blues'))
# Error in quantile.default(x, probs) : 
#  missing values and NaN's not allowed if 'na.rm' is FALSE

so choropleth() doesn't work as-is.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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