[GIS] R spatial aggregate, IDs out of order

aggregationrsp

HUC12_intersects is a SpatialPolygonsDataFrame object with over 5000 polygons

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

HUC12_intersects@data
AREA_ACR_1 GEOL_CODE new_soil HRU_ID
22093.3         2        2     10
22093.3         2        2     12
22093.3         2        2     10
22093.3         2        2     10
 1033.8         1        1      3
22093.3         2        2     10
22093.3         2        2      9
22093.3         2        2     10
22093.3         2        2     10
22093.3         2        2     10

HUC12_intersects@polygons[[1]]

An object of class "Polygons"
Slot "Polygons":
[[1]]
An object of class "Polygon"
Slot "labpt":
[1] 2007122.2  840584.2

Slot "area":
[1] 12538.28

Slot "hole":
[1] FALSE

Slot "ringDir":
[1] 1

Slot "coords":
         x        y
 [1,] 2007095 840527.3
 [2,] 2007049 840514.4
 [3,] 2007028 840547.0
 [4,] 2007061 840587.5
 [5,] 2007132 840631.9
 [6,] 2007174 840658.8
 [7,] 2007195 840639.8
 [8,] 2007207 840625.4
 [9,] 2007208 840594.1
 [10,] 2007151 840559.9
 [11,] 2007095 840527.3



 Slot "plotOrder":
 [1] 1

 Slot "labpt":
 [1] 2007122.2  840584.2

 Slot "ID":
 [1] "109"

 Slot "area":
 [1] 12538.28

The output from HUC12_dissolve is out of order

HUC12_dissolve<-aggregate(HUC12_intersects,by="HRU_ID")

HUC12_dissolve@data
  HRU_ID
1       1
2      10
3     100
4      12
5      14
6      15
7       2
8     202
9       3
10      5
11      7
12      8
13      9

I've tried sorting the data.frame and sorting the polygons to match the sorted data.frame but this does not preserve the spatial aspect of the polygons

order_HRUs<-order(HUC12_dissolve@data[,1],decreasing=F)
HUC12_dissolve2<-HUC12_dissolve
cnt<-0
for(i in seq(1,length(order_HRUs))){
  cnt<-cnt+1
  HUC12_dissolve2@polygons[[cnt]]<-HUC12_dissolve2@polygons[[which(order_HRUs==cnt)]]
}

This creates polygons with gaps and they are not labeled with the correct "HRU_ID"
enter image description here

I want to sort the data.frame, and I want the sorted data.frame "HRU_ID" to match the polygons

Best Answer

The aggregation is tracked using the row ids which is why the attribute id is out of order. If you want to reorder the data, which is honestly a bit arbitrary, operate on the row names not just the attributes.

You can use a vector of values as an index to resort the rows of a data.frame. If we create a data.frame and then pass a random vector of values that are the same length, within the bounds of n, we can resort the data.frame.

( x = data.frame(IDS=1:10, y=runif(10)) )
x[sample(1:10),]

Spatial objects honor this type of index sorting and subsetting. Here is a simple example where we resort a spatial object using the rownames. First, add packages and data as well as add a new IDS column to the sp meuse object.

library(sp)
data(meuse)
coordinates(meuse) <- ~x+y
( meuse@data <- data.frame(meuse@data, IDS=sample(1:nrow(meuse))) )

Here we create an object where the rownames and IDS are subset to a data.frame and then the spatial object is reordered using a bracket index with the new order of the rownames based on the sorting of the IDS.

x <- data.frame(r=row.names(meuse@data), IDS=meuse@data$IDS)
meuse <- meuse[match(x[order(x$IDS),]$r, row.names(meuse@data)),]
head(meuse@data)
Related Question