2

I need suggestion on how to sort a raster stack by dates. A reproducible example is in the following:

library(raster)

Create a reproducible rasterstack;

set.seed(123)
r1 <- raster(nrows = 6, ncols = 5, res = 30, xmn = 267195, xmx = 267375, ymn = 4016985, ymx = 4017135)
rr <- lapply(1:24, function(i) setValues(r1, runif(ncell(r1), min = -10000, max = 10000)))
ndvi <- stack(rr)
crs(ndvi) <- "+proj=utm +zone=43 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0"

Create date function;

dt <-as.data.frame(as.Date(c(
  '2017-01-03','2017-02-04','2018-11-22','2019-05-17','2013-04-14','2013-04-30',
  '2013-05-16','2013-06-01','2013-06-17','2013-07-03','2013-07-19','2013-08-04',
  '2013-08-20','2013-09-05','2013-10-07','2013-10-23','2013-11-08','2013-11-24',
  '2013-12-10','2013-12-26','2014-01-11','2014-01-27','2014-02-12','2014-02-28')))

Attach date to rasterstack;

ndvi <- setZ(ndvi, dt[,1], "SampleDate")
dates <- getZ(ndvi)
class(getZ(ndvi)) 
print(ndvi)

Now how can I sort or order the raster stack by dates (the oldest layer as the first layer and so on)?

2
  • 1
    A smaller example would be easier to see and work with! What works for ten dates will work for 768.
    – Spacedman
    Oct 5 '20 at 17:15
  • What if you change the names of your rasters to the dates or ranked number according to the dates and order the names. See the answer given: stackoverflow.com/questions/27483664/…
    – user19349
    Oct 5 '20 at 17:38
4

Use double brackets to re-order layers of a stack, and order to get the ordering. I stripped your example down to the first 10:

> ndvi_order = ndvi[[order(dates)]]
> ndvi_order
class      : RasterStack 
dimensions : 5, 6, 30, 10  (nrow, ncol, ncell, nlayers)
resolution : 30, 30  (x, y)
extent     : 267195, 267375, 4016985, 4017135  (xmin, xmax, ymin, ymax)
crs        : +proj=utm +zone=43 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
names      :   layer.5,   layer.6,   layer.7,   layer.8,   layer.9,  layer.10,   layer.1,   layer.2,   layer.3,   layer.4 
min values : -9790.658, -7778.071, -6953.068, -9046.727, -9599.514, -9873.984, -9158.809, -9507.726, -9987.505, -8785.589 
max values :  9684.384,  7493.647,  9712.818,  9222.096,  9387.128,  9642.807,  9885.396,  9260.485,  9699.140,  9089.477 
SampleDate  : 2013-04-14, 2013-04-30, 2013-05-16, 2013-06-01, 2013-06-17, 2013-07-03, 2017-01-03, 2017-02-04, 2018-11-22, 2019-05-17 
1
  • Nice solution. Perfect. Thanks
    – SA Khan
    Oct 6 '20 at 12:36
2

So, I never use the Z slot in stack objects. It is just as easy to manage a date vector. Let's assume that you did some sort of string manipulation to get the dates from the raster objects in your stack. Now, you want to sort the stack so that the date sequence is ordered correctly.

You already have a date vector but, please note that you do not need to coerce to a data.frame and it is good practice to explicitly define the date-time format when creating a date object.

First, I am grabbing a subsample of your dates so results are easier to see.

( dt.sub <- dt[sample(1:length(dt), 20)] )

Now, we can sort the dates and return an index of the original position, which relates to the raster stack.

( didx <- sort.int(dt.sub, index.return=TRUE) )

You can use the returned index x$ix to resort the stack using a simple double bracket.

dates <- sort.int(dt, index.return=TRUE)$x 
  ndvi <- ndvi[[sort.int(dt, index.return=TRUE)$ix]]

You now have a sorted dates vector and the raster stack is reordered accordingly. When I perform timeseries analysis I use the dates vector to query the raster stack using an index. This is where the which function if useful.

which(dates > "2015-12-31")

date.sub <- dates[which(dates > "2015-12-31")]
  ndvi.sub <- ndvi[[which(dates > "2015-12-31")]]
1
  • Thanks for the solution. I also learned from your solution how to use which() function.
    – SA Khan
    Oct 6 '20 at 12:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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