I have downloaded AOD data ("MCD19A2") using the MODIStsp package for several years.
library(raster)
library(stars)
The data I have extracted has the following format:
MCD19A2_Optical_Depth_055_2011_001.tif
MCD19A2_Optical_Depth_055_2011_002.tif ...
MCD19A2_Optical_Depth_055_2011_365.tif
Where files from each year are in a different folder.
I would like to be able to have weekly and monthly means and vectorize them. I have done this before with all the files from a year folder this way:
path_21<-paste0(wd,"/2021/Optical_Depth_055")
#list all files from the 2021 folder
all_modis_21<-list.files(path_21,
full.names = TRUE,
pattern = "*.tif$")
all_modis_21_st <- stack(all_modis_21)
all_modis_21_br<-brick(all_modis_21_st)
# calculate the mean of all files
mean_2021<-calc(all_modis_21_br, fun = mean, na.rm = TRUE)
path_21_mean<-paste0(wd,"MEANS/2021")
# store the mean in the "MEANS" folder
writeRaster(mean_2021, filename=file.path(path_21_mean,"mean_2021.tiff"),
format="GTiff", overwrite=TRUE)
mean_2021<-read_stars("Data/Pollution/MODIS/NASA_DATA/MEANS/2021/mean_2021.tiff")
wrap21 = st_warp(mean_2021, crs = 25831)
# vectorize the mean for 2021
p = st_as_sf(wrap21)
The previous code worked for creating the mean and vectorizing the files for the whole folder. But I don't know how to group them by week.
So far I have changed the name of the files to be able to work with dates.
to<-paste(as.Date(substr(list.files(path_21,pattern = "*.tif$"),start = 27,stop = 34),"%Y_%j"),".tif", sep="")
from<-list.files(path_21,pattern = "*.tif$")
raw_21<-data_frame(filename<-list.files(path_21,
pattern = "*.tif$"))
And the structure of the data for each folder looks like this:
head(raw_21)
1 2011-01-01.tif
2 2011-01-02.tif
3 2011-01-03.tif
4 2011-01-04.tif
5 2011-01-05.tif
6 2011-01-06.tif
7 2011-01-07.tif
8 2011-01-08.tif
9 2011-01-09.tif
10 2011-01-10.tif
But I am fairly new to R and I am lost on how to proceed from here. I would appreciate any help on how to follow :)
You want to summarize daily raster data by week, project to a different CRS, and then transform the raster data to polygons.
Here are some example filenames:
ff <- paste0("MCD19A2_Optical_Depth_055_2011_", c("001", "002", "040", "090", 120:125, 200:205, 300), ".tif")
head(ff)
#[1] "MCD19A2_Optical_Depth_055_2011_001.tif"
#[2] "MCD19A2_Optical_Depth_055_2011_002.tif"
#[3] "MCD19A2_Optical_Depth_055_2011_040.tif"
#[4] "MCD19A2_Optical_Depth_055_2011_090.tif"
#[5] "MCD19A2_Optical_Depth_055_2011_120.tif"
#[6] "MCD19A2_Optical_Depth_055_2011_121.tif"
Now you can extract the date like this
d <- gsub("MCD19A2_Optical_Depth_055_", "", basename(ff))
year <- as.numeric(substr(d, 1, 4))
doy <- as.numeric(substr(d, 6, 9))
date <- as.Date(doy, origin=paste(year-1, "-12-31", sep=""))
Create a SpatRaster, set the dates, and get the mean for each week
x <- rast(ff)
terra::time(x) <- date
r <- tapp(x, "week", mean, na.rm=TRUE)
But note that in this year, Jan 1 is part of week 52. See ?strftime
.
week <- strftime(date, format = "%V")
week
# [1] "52" "52" "06" "13" "17" "17" "18" "18" "18" "18" "29" "29"
# [13] "29" "29" "29" "29" "43"
You can also define your own 7-day periods that start on Jan 1 like this
myweek <- floor(doy / 7) + 1
myweek <- formatC(myweek, width=2, flag=0)
myweek
#[1] "01" "01" "06" "13" "18" "18" "18" "18" "18" "18" "29" "29" "29" "30" "30" "30" "43"
And use that with tapp
r <- tapp(x, myweek, mean, na.rm=TRUE)
Now you can project and create polygons
r <- project(r, "epsg:25831")
p <- as.polygons(r)
writeVector(p, "MCD19A2_Optical_Depth.shp")
A more "manual" approach could be to write a loop
uweeks <- unique(week)
rlst <- lapply(uweeks, function(w) {
ffw <- ff[week == w]
mean(rast(ffw))
}
r <- rast(rlst)
r <- project(r, "epsg:25831")
p <- as.polygons(r)
It works the same for months. To get the month from a date, you can do
format(date,"%m")
#[1] "01" "01" "02" "03" "04" "05" "05" "05" "05" "05" "07" "07" "07" "07" "07" "07" "10"
Final notes:
Transforming raster data to polygons is not a good idea. It is almost certainly a major mistake in your workflow. But as you are not saying why you are doing this, we cannot point you to a better solution.
It is better not to use the term "vectorize" as that has a different meaning in the context of R programming; plus you could also "vectorize" raster data to lines or points, so the term is not very clear.