Check this out
Now, what I did was supply the Polygon function the coordinates that define a polygon (notice that the first and last row match--it's closed). It creates an S4 Polygon class object that has a slot for "label point" (labpt). I only tested out a much more complicated process (like, 3 more nested steps) on the first county, but I got the centroid to be the same as the label point. Thus, the provided label points seem to be the centroids, from what I can guess. I provide this as a way for you to check what your averaging the polygon corners produces to what the actual centroids are (the actual computation is a little more involved). I tried to use tapply instead of by, but this is one of those times when they don't match up. Using tapply returns an error "arguments must have the same length." To me, by always seems to work as if I did s/lapply(split(df, df$factor), someFun). So, screw tapply! I also tried to supply Polygon to an aggregate call (so it works on each county), but that didn't work out at all.
Now, what did I have to do to get the centroids? Well, it's as easy as just saying coordinates and supplying it a SpatialPolygons object. Easy, right? No! What is a SpatialPolygons object? It's a list of Polygons. What is a Polygons object? It's a list of Polygon! So I had to take Polygon(df[df$subregion == "albany", c(1,2)]) and make it a list. But wait, there's more! Polygons apparently needs labels, so I put that list of one Polygon into 'y' and ran Polygons(y, "shutup!") and got my Polygons object (a list of S4 Polygon with a labeled name slot). Now, we can't just toss this new Polygons object into SpatialPolygons. It requires an integer vector to specify the number of Polygons in the list or some ****, as well as a coordinate reference system. Thus, we have to do
So like I said, it may only be a few more steps, but it is a pain! I hope it's just due to my ignorance of sp and it's spatial S4 objects, but the return result of running coordinates on the above SpatialPolygons object was the same coordinates as Polygon(df[df$subregion=="albany", c(1:2)])@labpt. I was not going to bother with seeing if it held consistent with the other centroids calculated.
Code:
library(sp)
library(maps)
df <- map_data('county', 'new york') # Grab the New York region county data
centroids <- by(df, df$region, function(county) Polygon(county[c('long', 'lat')])@labpt) # Returns a county-named list of label points
centroids <- do.call("rbind", centroids) # Convert into Data Frame
names(centroids) <- c('long', 'lat')
Now, what did I have to do to get the centroids? Well, it's as easy as just saying coordinates and supplying it a SpatialPolygons object. Easy, right? No! What is a SpatialPolygons object? It's a list of Polygons. What is a Polygons object? It's a list of Polygon! So I had to take Polygon(df[df$subregion == "albany", c(1,2)]) and make it a list. But wait, there's more! Polygons apparently needs labels, so I put that list of one Polygon into 'y' and ran Polygons(y, "shutup!") and got my Polygons object (a list of S4 Polygon with a labeled name slot). Now, we can't just toss this new Polygons object into SpatialPolygons. It requires an integer vector to specify the number of Polygons in the list or some ****, as well as a coordinate reference system. Thus, we have to do
Code:
z <- ... Polygons go here ...
SpatialPolygons(z, as.integer(1), CRS("+proj=longlat")) # Yes, "1" is not an integer!! ugh