Skip to main content
added 514 characters in body
Source Link
dimfalk
  • 1.4k
  • 1
  • 7
  • 17
# list files available, I created 12 files beforehand
files <- list.files(pattern = "*.tif")

# using filenames following your pattern
head(files)
#> [1] "NDVI-2017-07-09.tif"
#> [2] "NDVI-2017-08-09.tif"
#> [3] "NDVI-2017-09-09.tif"
#> [4] "NDVI-2017-10-09.tif"
#> [5] "NDVI-2017-11-09.tif"
#> [6] "NDVI-2017-12-09.tif"

# create a SpatRast object using terra
stack <- terra::rast(files)

# note that nlyr = 12, so this is basically a raster stack
stack
#> class       : SpatRaster 
#> dimensions  : 900, 900, 12  (nrow, ncol, nlyr)
#> resolution  : 0.001111111, 0.001111111  (x, y)
#> extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> sources     : NDVI-2017-07-09.tif  
#>               NDVI-2017-08-09.tif  
#>               NDVI-2017-09-09.tif  
#>               ... and 9 more source(s)
#> names       : NDVI-~07-09, NDVI-~08-09, NDVI-~09-09, NDVI-~10-09, NDVI-~11-09, NDVI-~12-09, ... 
#> min values  :       -3840,       -3840,       -3840,       -3840,       -3840,       -3840, ... 
#> max values  :        3881,        3881,        3881,        3881,        3881,        3881, ...

# parse timestamps from names attribute and set the time attribute
terra::time(stack) <- names(stack) |> stringr::str_sub(start = 6, end = 15) |> strptime(format = "%Y-%m-%d", tz = "UTC")

# your stack now has time information ranging from 2017-07-09 to 2018-06-09
stack
#> class       : SpatRaster 
#> dimensions  : 900, 900, 12  (nrow, ncol, nlyr)
#> resolution  : 0.001111111, 0.001111111  (x, y)
#> extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> sources     : NDVI-2017-07-09.tif  
#>               NDVI-2017-08-09.tif  
#>               NDVI-2017-09-09.tif  
#>               ... and 9 more source(s)
#> names       : NDVI-~07-09, NDVI-~08-09, NDVI-~09-09, NDVI-~10-09, NDVI-~11-09, NDVI-~12-09, ... 
#> min values  :       -3840,       -3840,       -3840,       -3840,       -3840,       -3840, ... 
#> max values  :        3881,        3881,        3881,        3881,        3881,        3881, ... 
#> time        : 2017-07-09 to 2018-06-09 UTC

# which you can either make use nowof topartial subsetmatching yourusing stack`[]` querying layer names 
# holding timestamps in your case...
stack["2017"]
#> class       : SpatRaster 
#> dimensions  : 900, 900, 6  (nrow, ncol, nlyr)
#> resolution  : 0.001111111, 0.001111111  (x, y)
#> extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> sources     : NDVI-2017-07-09.tif  
#>               NDVI-2017-08-09.tif  
#>               NDVI-2017-09-09.tif  
#>               ... and 3 more source(s)
#> names       : NDVI-~07-09, NDVI-~08-09, NDVI-~09-09, NDVI-~10-09, NDVI-~11-09, NDVI-~12-09 
#> min values  :       -3840,       -3840,       -3840,       -3840,       -3840,       -3840 
#> max values  :        3881,        3881,        3881,        3881,        3881,        3881 
#> time        : 2017-07-09 to 2017-12-09 UTC

stack["2017# ... or construct an index vector as input based on your time attribute
stack[[time(stack) >= "2017-10"]01-01" & time(stack) < "2018-01-01"]]
#> class       : SpatRaster 
#> dimensions  : 900, 900, 16  (nrow, ncol, nlyr)
#> resolution  : 0.001111111, 0.001111111  (x, y)
#> extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> source sources     : NDVI-2017-1007-09.tif  
#> name        :      NDVI-2017-1008-09.tif  
#> min value             NDVI-2017-09-09.tif  
#>               ... and 3 more source(s)
#> names       : NDVI-~07-09, NDVI-~08-09, NDVI-~09-09, NDVI-~10-09, NDVI-~11-09, NDVI-~12-09 
#> min values  :       -3840,       -3840,       -3840,       -3840,       -3840,       -3840 
#> max value values  :        3881,        3881,        3881,        3881,        3881,        3881 
#> time        : 2017-1007-09 to 2017-12-09 UTC
# list files available, I created 12 files beforehand
files <- list.files(pattern = "*.tif")

# using filenames following your pattern
head(files)
#> [1] "NDVI-2017-07-09.tif"
#> [2] "NDVI-2017-08-09.tif"
#> [3] "NDVI-2017-09-09.tif"
#> [4] "NDVI-2017-10-09.tif"
#> [5] "NDVI-2017-11-09.tif"
#> [6] "NDVI-2017-12-09.tif"

# create a SpatRast object using terra
stack <- terra::rast(files)

# note that nlyr = 12, so this is basically a raster stack
stack
#> class       : SpatRaster 
#> dimensions  : 900, 900, 12  (nrow, ncol, nlyr)
#> resolution  : 0.001111111, 0.001111111  (x, y)
#> extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> sources     : NDVI-2017-07-09.tif  
#>               NDVI-2017-08-09.tif  
#>               NDVI-2017-09-09.tif  
#>               ... and 9 more source(s)
#> names       : NDVI-~07-09, NDVI-~08-09, NDVI-~09-09, NDVI-~10-09, NDVI-~11-09, NDVI-~12-09, ... 
#> min values  :       -3840,       -3840,       -3840,       -3840,       -3840,       -3840, ... 
#> max values  :        3881,        3881,        3881,        3881,        3881,        3881, ...

# parse timestamps from names attribute and set the time attribute
terra::time(stack) <- names(stack) |> stringr::str_sub(start = 6, end = 15) |> strptime(format = "%Y-%m-%d", tz = "UTC")

# your stack now has time information ranging from 2017-07-09 to 2018-06-09
stack
#> class       : SpatRaster 
#> dimensions  : 900, 900, 12  (nrow, ncol, nlyr)
#> resolution  : 0.001111111, 0.001111111  (x, y)
#> extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> sources     : NDVI-2017-07-09.tif  
#>               NDVI-2017-08-09.tif  
#>               NDVI-2017-09-09.tif  
#>               ... and 9 more source(s)
#> names       : NDVI-~07-09, NDVI-~08-09, NDVI-~09-09, NDVI-~10-09, NDVI-~11-09, NDVI-~12-09, ... 
#> min values  :       -3840,       -3840,       -3840,       -3840,       -3840,       -3840, ... 
#> max values  :        3881,        3881,        3881,        3881,        3881,        3881, ... 
#> time        : 2017-07-09 to 2018-06-09 UTC

# which you can use now to subset your stack  
stack["2017"]
#> class       : SpatRaster 
#> dimensions  : 900, 900, 6  (nrow, ncol, nlyr)
#> resolution  : 0.001111111, 0.001111111  (x, y)
#> extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> sources     : NDVI-2017-07-09.tif  
#>               NDVI-2017-08-09.tif  
#>               NDVI-2017-09-09.tif  
#>               ... and 3 more source(s)
#> names       : NDVI-~07-09, NDVI-~08-09, NDVI-~09-09, NDVI-~10-09, NDVI-~11-09, NDVI-~12-09 
#> min values  :       -3840,       -3840,       -3840,       -3840,       -3840,       -3840 
#> max values  :        3881,        3881,        3881,        3881,        3881,        3881 
#> time        : 2017-07-09 to 2017-12-09 UTC

stack["2017-10"]
#> class       : SpatRaster 
#> dimensions  : 900, 900, 1  (nrow, ncol, nlyr)
#> resolution  : 0.001111111, 0.001111111  (x, y)
#> extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> source      : NDVI-2017-10-09.tif 
#> name        : NDVI-2017-10-09 
#> min value   :           -3840 
#> max value   :            3881 
#> time        : 2017-10-09 UTC
# list files available, I created 12 files beforehand
files <- list.files(pattern = "*.tif")

# using filenames following your pattern
head(files)
#> [1] "NDVI-2017-07-09.tif"
#> [2] "NDVI-2017-08-09.tif"
#> [3] "NDVI-2017-09-09.tif"
#> [4] "NDVI-2017-10-09.tif"
#> [5] "NDVI-2017-11-09.tif"
#> [6] "NDVI-2017-12-09.tif"

# create a SpatRast object using terra
stack <- terra::rast(files)

# note that nlyr = 12, so this is basically a raster stack
stack
#> class       : SpatRaster 
#> dimensions  : 900, 900, 12  (nrow, ncol, nlyr)
#> resolution  : 0.001111111, 0.001111111  (x, y)
#> extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> sources     : NDVI-2017-07-09.tif  
#>               NDVI-2017-08-09.tif  
#>               NDVI-2017-09-09.tif  
#>               ... and 9 more source(s)
#> names       : NDVI-~07-09, NDVI-~08-09, NDVI-~09-09, NDVI-~10-09, NDVI-~11-09, NDVI-~12-09, ... 
#> min values  :       -3840,       -3840,       -3840,       -3840,       -3840,       -3840, ... 
#> max values  :        3881,        3881,        3881,        3881,        3881,        3881, ...

# parse timestamps from names attribute and set the time attribute
terra::time(stack) <- names(stack) |> stringr::str_sub(start = 6, end = 15) |> strptime(format = "%Y-%m-%d", tz = "UTC")

# your stack now has time information ranging from 2017-07-09 to 2018-06-09
stack
#> class       : SpatRaster 
#> dimensions  : 900, 900, 12  (nrow, ncol, nlyr)
#> resolution  : 0.001111111, 0.001111111  (x, y)
#> extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> sources     : NDVI-2017-07-09.tif  
#>               NDVI-2017-08-09.tif  
#>               NDVI-2017-09-09.tif  
#>               ... and 9 more source(s)
#> names       : NDVI-~07-09, NDVI-~08-09, NDVI-~09-09, NDVI-~10-09, NDVI-~11-09, NDVI-~12-09, ... 
#> min values  :       -3840,       -3840,       -3840,       -3840,       -3840,       -3840, ... 
#> max values  :        3881,        3881,        3881,        3881,        3881,        3881, ... 
#> time        : 2017-07-09 to 2018-06-09 UTC

# you can either make use of partial matching using `[]` querying layer names 
# holding timestamps in your case...
stack["2017"]
#> class       : SpatRaster 
#> dimensions  : 900, 900, 6  (nrow, ncol, nlyr)
#> resolution  : 0.001111111, 0.001111111  (x, y)
#> extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> sources     : NDVI-2017-07-09.tif  
#>               NDVI-2017-08-09.tif  
#>               NDVI-2017-09-09.tif  
#>               ... and 3 more source(s)
#> names       : NDVI-~07-09, NDVI-~08-09, NDVI-~09-09, NDVI-~10-09, NDVI-~11-09, NDVI-~12-09 
#> min values  :       -3840,       -3840,       -3840,       -3840,       -3840,       -3840 
#> max values  :        3881,        3881,        3881,        3881,        3881,        3881 
#> time        : 2017-07-09 to 2017-12-09 UTC

# ... or construct an index vector as input based on your time attribute
stack[[time(stack) >= "2017-01-01" & time(stack) < "2018-01-01"]]
#> class       : SpatRaster 
#> dimensions  : 900, 900, 6  (nrow, ncol, nlyr)
#> resolution  : 0.001111111, 0.001111111  (x, y)
#> extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> sources     : NDVI-2017-07-09.tif  
#>               NDVI-2017-08-09.tif  
#>               NDVI-2017-09-09.tif  
#>               ... and 3 more source(s)
#> names       : NDVI-~07-09, NDVI-~08-09, NDVI-~09-09, NDVI-~10-09, NDVI-~11-09, NDVI-~12-09 
#> min values  :       -3840,       -3840,       -3840,       -3840,       -3840,       -3840 
#> max values  :        3881,        3881,        3881,        3881,        3881,        3881 
#> time        : 2017-07-09 to 2017-12-09 UTC
added 41 characters in body
Source Link
dimfalk
  • 1.4k
  • 1
  • 7
  • 17
# list files available, I created 12 files beforehand
files <- list.files(pattern = "*.tif")

# using filenames following your pattern
head(files)
#> [1] "NDVI-2017-07-09.tif"
#> [2] "NDVI-2017-08-09.tif"
#> [3] "NDVI-2017-09-09.tif"
#> [4] "NDVI-2017-10-09.tif"
#> [5] "NDVI-2017-11-09.tif"
#> [6] "NDVI-2017-12-09.tif"

# create a SpatRast object using terra
stack <- terra::rast(files)

# note that nlyr = 12, so this is basically a raster stack
stack
#> class       : SpatRaster 
#> dimensions  : 900, 900, 12  (nrow, ncol, nlyr)
#> resolution  : 0.001111111, 0.001111111  (x, y)
#> extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> sources     : NDVI-2017-07-09.tif  
#>               NDVI-2017-08-09.tif  
#>               NDVI-2017-09-09.tif  
#>               ... and 9 more source(s)
#> names       : NDVI-~07-09, NDVI-~08-09, NDVI-~09-09, NDVI-~10-09, NDVI-~11-09, NDVI-~12-09, ... 
#> min values  :       -3840,       -3840,       -3840,       -3840,       -3840,       -3840, ... 
#> max values  :        3881,        3881,        3881,        3881,        3881,        3881, ...

# parse timestamps from names attribute and set the time attribute
terra::time(stack) <- names(stack) |> stringr::str_sub(start = 6, end = 15) |> strptime(format = "%Y-%m-%d", tz = "UTC")

# your stack now has time information ranging from 2017-07-09 to 2018-06-09
stack
#> class       : SpatRaster 
#> dimensions  : 900, 900, 12  (nrow, ncol, nlyr)
#> resolution  : 0.001111111, 0.001111111  (x, y)
#> extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> sources     : NDVI-2017-07-09.tif  
#>               NDVI-2017-08-09.tif  
#>               NDVI-2017-09-09.tif  
#>               ... and 9 more source(s)
#> names       : NDVI-~07-09, NDVI-~08-09, NDVI-~09-09, NDVI-~10-09, NDVI-~11-09, NDVI-~12-09, ... 
#> min values  :       -3840,       -3840,       -3840,       -3840,       -3840,       -3840, ... 
#> max values  :        3881,        3881,        3881,        3881,        3881,        3881, ... 
#> time        : 2017-07-09 to 2018-06-09 UTC

# which you can use now to subset your stack  
stack["2017"]
#> class       : SpatRaster 
#> dimensions  : 900, 900, 6  (nrow, ncol, nlyr)
#> resolution  : 0.001111111, 0.001111111  (x, y)
#> extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> sources     : NDVI-2017-07-09.tif  
#>               NDVI-2017-08-09.tif  
#>               NDVI-2017-09-09.tif  
#>               ... and 3 more source(s)
#> names       : NDVI-~07-09, NDVI-~08-09, NDVI-~09-09, NDVI-~10-09, NDVI-~11-09, NDVI-~12-09 
#> min values  :       -3840,       -3840,       -3840,       -3840,       -3840,       -3840 
#> max values  :        3881,        3881,        3881,        3881,        3881,        3881 
#> time        : 2017-07-09 to 2017-12-09 UTC

stack["2017-10"]
#> class       : SpatRaster 
#> dimensions  : 900, 900, 1  (nrow, ncol, nlyr)
#> resolution  : 0.001111111, 0.001111111  (x, y)
#> extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> source      : NDVI-2017-10-09.tif 
#> name        : NDVI-2017-10-09 
#> min value   :           -3840 
#> max value   :            3881 
#> time        : 2017-10-09 UTC
# list files
files <- list.files(pattern = "*.tif")

# using filenames following your pattern
head(files)
#> [1] "NDVI-2017-07-09.tif"
#> [2] "NDVI-2017-08-09.tif"
#> [3] "NDVI-2017-09-09.tif"
#> [4] "NDVI-2017-10-09.tif"
#> [5] "NDVI-2017-11-09.tif"
#> [6] "NDVI-2017-12-09.tif"

# create a SpatRast object using terra
stack <- terra::rast(files)

# note that nlyr = 12, so this is basically a raster stack
stack
#> class       : SpatRaster 
#> dimensions  : 900, 900, 12  (nrow, ncol, nlyr)
#> resolution  : 0.001111111, 0.001111111  (x, y)
#> extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> sources     : NDVI-2017-07-09.tif  
#>               NDVI-2017-08-09.tif  
#>               NDVI-2017-09-09.tif  
#>               ... and 9 more source(s)
#> names       : NDVI-~07-09, NDVI-~08-09, NDVI-~09-09, NDVI-~10-09, NDVI-~11-09, NDVI-~12-09, ... 
#> min values  :       -3840,       -3840,       -3840,       -3840,       -3840,       -3840, ... 
#> max values  :        3881,        3881,        3881,        3881,        3881,        3881, ...

# parse timestamps from names attribute and set the time attribute
terra::time(stack) <- names(stack) |> stringr::str_sub(start = 6, end = 15) |> strptime(format = "%Y-%m-%d", tz = "UTC")

# your stack now has time information ranging from 2017-07-09 to 2018-06-09
stack
#> class       : SpatRaster 
#> dimensions  : 900, 900, 12  (nrow, ncol, nlyr)
#> resolution  : 0.001111111, 0.001111111  (x, y)
#> extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> sources     : NDVI-2017-07-09.tif  
#>               NDVI-2017-08-09.tif  
#>               NDVI-2017-09-09.tif  
#>               ... and 9 more source(s)
#> names       : NDVI-~07-09, NDVI-~08-09, NDVI-~09-09, NDVI-~10-09, NDVI-~11-09, NDVI-~12-09, ... 
#> min values  :       -3840,       -3840,       -3840,       -3840,       -3840,       -3840, ... 
#> max values  :        3881,        3881,        3881,        3881,        3881,        3881, ... 
#> time        : 2017-07-09 to 2018-06-09 UTC

# which you can use now to subset your stack  
stack["2017"]
#> class       : SpatRaster 
#> dimensions  : 900, 900, 6  (nrow, ncol, nlyr)
#> resolution  : 0.001111111, 0.001111111  (x, y)
#> extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> sources     : NDVI-2017-07-09.tif  
#>               NDVI-2017-08-09.tif  
#>               NDVI-2017-09-09.tif  
#>               ... and 3 more source(s)
#> names       : NDVI-~07-09, NDVI-~08-09, NDVI-~09-09, NDVI-~10-09, NDVI-~11-09, NDVI-~12-09 
#> min values  :       -3840,       -3840,       -3840,       -3840,       -3840,       -3840 
#> max values  :        3881,        3881,        3881,        3881,        3881,        3881 
#> time        : 2017-07-09 to 2017-12-09 UTC

stack["2017-10"]
#> class       : SpatRaster 
#> dimensions  : 900, 900, 1  (nrow, ncol, nlyr)
#> resolution  : 0.001111111, 0.001111111  (x, y)
#> extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> source      : NDVI-2017-10-09.tif 
#> name        : NDVI-2017-10-09 
#> min value   :           -3840 
#> max value   :            3881 
#> time        : 2017-10-09 UTC
# list files available, I created 12 files beforehand
files <- list.files(pattern = "*.tif")

# using filenames following your pattern
head(files)
#> [1] "NDVI-2017-07-09.tif"
#> [2] "NDVI-2017-08-09.tif"
#> [3] "NDVI-2017-09-09.tif"
#> [4] "NDVI-2017-10-09.tif"
#> [5] "NDVI-2017-11-09.tif"
#> [6] "NDVI-2017-12-09.tif"

# create a SpatRast object using terra
stack <- terra::rast(files)

# note that nlyr = 12, so this is basically a raster stack
stack
#> class       : SpatRaster 
#> dimensions  : 900, 900, 12  (nrow, ncol, nlyr)
#> resolution  : 0.001111111, 0.001111111  (x, y)
#> extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> sources     : NDVI-2017-07-09.tif  
#>               NDVI-2017-08-09.tif  
#>               NDVI-2017-09-09.tif  
#>               ... and 9 more source(s)
#> names       : NDVI-~07-09, NDVI-~08-09, NDVI-~09-09, NDVI-~10-09, NDVI-~11-09, NDVI-~12-09, ... 
#> min values  :       -3840,       -3840,       -3840,       -3840,       -3840,       -3840, ... 
#> max values  :        3881,        3881,        3881,        3881,        3881,        3881, ...

# parse timestamps from names attribute and set the time attribute
terra::time(stack) <- names(stack) |> stringr::str_sub(start = 6, end = 15) |> strptime(format = "%Y-%m-%d", tz = "UTC")

# your stack now has time information ranging from 2017-07-09 to 2018-06-09
stack
#> class       : SpatRaster 
#> dimensions  : 900, 900, 12  (nrow, ncol, nlyr)
#> resolution  : 0.001111111, 0.001111111  (x, y)
#> extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> sources     : NDVI-2017-07-09.tif  
#>               NDVI-2017-08-09.tif  
#>               NDVI-2017-09-09.tif  
#>               ... and 9 more source(s)
#> names       : NDVI-~07-09, NDVI-~08-09, NDVI-~09-09, NDVI-~10-09, NDVI-~11-09, NDVI-~12-09, ... 
#> min values  :       -3840,       -3840,       -3840,       -3840,       -3840,       -3840, ... 
#> max values  :        3881,        3881,        3881,        3881,        3881,        3881, ... 
#> time        : 2017-07-09 to 2018-06-09 UTC

# which you can use now to subset your stack  
stack["2017"]
#> class       : SpatRaster 
#> dimensions  : 900, 900, 6  (nrow, ncol, nlyr)
#> resolution  : 0.001111111, 0.001111111  (x, y)
#> extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> sources     : NDVI-2017-07-09.tif  
#>               NDVI-2017-08-09.tif  
#>               NDVI-2017-09-09.tif  
#>               ... and 3 more source(s)
#> names       : NDVI-~07-09, NDVI-~08-09, NDVI-~09-09, NDVI-~10-09, NDVI-~11-09, NDVI-~12-09 
#> min values  :       -3840,       -3840,       -3840,       -3840,       -3840,       -3840 
#> max values  :        3881,        3881,        3881,        3881,        3881,        3881 
#> time        : 2017-07-09 to 2017-12-09 UTC

stack["2017-10"]
#> class       : SpatRaster 
#> dimensions  : 900, 900, 1  (nrow, ncol, nlyr)
#> resolution  : 0.001111111, 0.001111111  (x, y)
#> extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> source      : NDVI-2017-10-09.tif 
#> name        : NDVI-2017-10-09 
#> min value   :           -3840 
#> max value   :            3881 
#> time        : 2017-10-09 UTC
Source Link
dimfalk
  • 1.4k
  • 1
  • 7
  • 17

I'd like to show you an alternative approach using terra instead of raster since this a little bit more elegant from my point of view:

# list files
files <- list.files(pattern = "*.tif")

# using filenames following your pattern
head(files)
#> [1] "NDVI-2017-07-09.tif"
#> [2] "NDVI-2017-08-09.tif"
#> [3] "NDVI-2017-09-09.tif"
#> [4] "NDVI-2017-10-09.tif"
#> [5] "NDVI-2017-11-09.tif"
#> [6] "NDVI-2017-12-09.tif"

# create a SpatRast object using terra
stack <- terra::rast(files)

# note that nlyr = 12, so this is basically a raster stack
stack
#> class       : SpatRaster 
#> dimensions  : 900, 900, 12  (nrow, ncol, nlyr)
#> resolution  : 0.001111111, 0.001111111  (x, y)
#> extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> sources     : NDVI-2017-07-09.tif  
#>               NDVI-2017-08-09.tif  
#>               NDVI-2017-09-09.tif  
#>               ... and 9 more source(s)
#> names       : NDVI-~07-09, NDVI-~08-09, NDVI-~09-09, NDVI-~10-09, NDVI-~11-09, NDVI-~12-09, ... 
#> min values  :       -3840,       -3840,       -3840,       -3840,       -3840,       -3840, ... 
#> max values  :        3881,        3881,        3881,        3881,        3881,        3881, ...

# parse timestamps from names attribute and set the time attribute
terra::time(stack) <- names(stack) |> stringr::str_sub(start = 6, end = 15) |> strptime(format = "%Y-%m-%d", tz = "UTC")

# your stack now has time information ranging from 2017-07-09 to 2018-06-09
stack
#> class       : SpatRaster 
#> dimensions  : 900, 900, 12  (nrow, ncol, nlyr)
#> resolution  : 0.001111111, 0.001111111  (x, y)
#> extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> sources     : NDVI-2017-07-09.tif  
#>               NDVI-2017-08-09.tif  
#>               NDVI-2017-09-09.tif  
#>               ... and 9 more source(s)
#> names       : NDVI-~07-09, NDVI-~08-09, NDVI-~09-09, NDVI-~10-09, NDVI-~11-09, NDVI-~12-09, ... 
#> min values  :       -3840,       -3840,       -3840,       -3840,       -3840,       -3840, ... 
#> max values  :        3881,        3881,        3881,        3881,        3881,        3881, ... 
#> time        : 2017-07-09 to 2018-06-09 UTC

# which you can use now to subset your stack  
stack["2017"]
#> class       : SpatRaster 
#> dimensions  : 900, 900, 6  (nrow, ncol, nlyr)
#> resolution  : 0.001111111, 0.001111111  (x, y)
#> extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> sources     : NDVI-2017-07-09.tif  
#>               NDVI-2017-08-09.tif  
#>               NDVI-2017-09-09.tif  
#>               ... and 3 more source(s)
#> names       : NDVI-~07-09, NDVI-~08-09, NDVI-~09-09, NDVI-~10-09, NDVI-~11-09, NDVI-~12-09 
#> min values  :       -3840,       -3840,       -3840,       -3840,       -3840,       -3840 
#> max values  :        3881,        3881,        3881,        3881,        3881,        3881 
#> time        : 2017-07-09 to 2017-12-09 UTC

stack["2017-10"]
#> class       : SpatRaster 
#> dimensions  : 900, 900, 1  (nrow, ncol, nlyr)
#> resolution  : 0.001111111, 0.001111111  (x, y)
#> extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 
#> source      : NDVI-2017-10-09.tif 
#> name        : NDVI-2017-10-09 
#> min value   :           -3840 
#> max value   :            3881 
#> time        : 2017-10-09 UTC

Personally, I would leave it this way and not create a separate stack per year because querying is quite comfortable. If you wish to split your stack per year nevertheless, you could do something like this, even if this is maybe not the most elegant way to accomplish:

# get unique years from time attribute
years <- terra::time(stack) |> format("%Y") |> unique()

# loop over years and create new sub-stacks
for (i in 1:length(years)) {
  
  assign(paste0("NDVI_stack_", years[i]),
         
         stack[years[i]])  
}