I have 175 tif files including gridded data for various crops for the whole globe (land). I want to create a single raster data set that only contains the index of the highest value. So that for each cell I know which crop has the highest value.
My code works. But if I run the calc() function I sometimes get an error that I cannot explain:
Error in .calcTest(x[1:5], fun, na.rm, forcefun, forceapply) : cannot use this function. Perhaps add '...' or 'na.rm' to the function arguments?
library(raster)
# Get the file names for later import
file_list <- list.files(path = "C:/folder/test", full.names = TRUE)
filtered_file_list <- file_list[grep("HarvestedAreaFraction.tif",file_list,fixed=TRUE)]
#init
raster_stack <- stack()
crop_names <- character() #list to save the index of crops
for (file_path in filtered_file_list){
raster_layer <- raster(file_path)
# Aggregate the raster to a 1-degree resolution, all tif-files have the same resolution
aggregated_raster_layer <- aggregate(raster_layer, fact=c(12,12), fun=mean)
raster_layer <- na.omit(aggregated_raster_layer)
raster_stack <- addLayer(raster_stack, raster_layer)
crop_name <- gsub(".*/(.*?)_HarvestedAreaFraction\\.tif$", "\\1", file_path)
crop_names <- c(crop_names, crop_name)
}
# Function to get the name of the crop with the maximum fraction
get_max_crop_name <- function(x, na.rm = TRUE, ...) {
max_index <- which.max(x)
# max_name <- crop_names[max_index]
if (length(max_index) == 0 || all(x == 0) || all(is.na(x))) {
max_name <- 0
} else {
max_name <- max_index
}
return(max_name)
}
max_crop_raster <- calc(raster_stack, fun=get_max_crop_name, na.rm=TRUE)
The error only occurs when I import the larger tif-files. Out of the 175 files about 100 are about 30MB and the other are about 2-3MB. It works fine for the smaller ones but as soon as I include one of the larger ones I get this error
Any ideas?
The reason this does not work is that your function is not vectorized, because
if
statements can only evaluate one value at a time.You do not need any of this anyway, as you can use
wich.max
. like this (with "terra", the replacement for "raster"):