Extract values from raster matching csv and raster filenames

113 Views Asked by At

I have a folder with many csv files. Each file has several columns as well as lat and long columns. Another folder have many rasters in tif format. The .csv files are named based on Julian date (e.g. 251.csv), and so the rasters (e.g. 251.tif). I would like to be able to add the raster value to the csv with matching name and save to a new csv in R. What I want to achieve is this:

raster<-raster("c:/temp/TIFF/2001/273.tif")
points<-read.csv("c:/temp/csv/2001/273.csv")
coordinates(points)=~long+lat
rasValue=extract(raster,points)
combinePointValue <- cbind(points,rasValue)
head(combinePointValue)
library(spdplyr)
combinePointValue <- combinePointValue %>% 
  rename(chloro = 10)
write.table(combinePointValue,file="c:/temp/2001/chloro/273_chloro.csv",append=FALSE, 
sep=",",row.names=FALSE, col.names=TRUE)

Considering the many csv and many tif files, I would prefer avoiding having to type this over and over. Anyone able to help? Many thanks in advance! Ilaria

2

There are 2 best solutions below

4
Elia On

It is better to provide a minimal reproducible example since your code can not run without your specific data. However, if I understand well, you can try something like this. Since csv and tif files have the same name, you can sort them and loop through the file index. You can use the original path of csv files to save a new file just by pasting the suffix "_chloro:

library(spdplyr)
csv <- sort(list.files("c:/temp/csv/2001/",full.names = T))
tif <- sort(list.files("c:/temp/TIFF/2001/",full.names = T))

lapply(1:length(csv),function(i){
  raster<-raster(tif[i])
  points<-read.csv(csv[i])
  coordinates(points)=~long+lat
  rasValue=extract(raster,points)
  combinePointValue <- cbind(points,rasValue)
  head(combinePointValue)
  combinePointValue <- combinePointValue %>% 
    rename(chloro = 10)
  write.table(combinePointValue,file=paste0(tools::file_path_sans_ext(csv[i]),"_chloro.csv"),append=FALSE, 
              sep=",",row.names=FALSE, col.names=TRUE)
}) 
2
Micha On

SInce the R spatial "ecosystem" is undergoing dramatic changes over the past few years, and package like sp and raster will be deprecated, you might consider a solution based on the terra package. It would go something like:

# Not tested!    
library(terra)
csv_path = "c:/temp/csv/2001/"
tif_path = "c:/temp/TIFF/2001/"
tif_list = list.files(file.path(tif_path, pattern = "*.tif", full.names = FALSE)
result_list = lapply(1:length(tif_list), function(i) {
  tif_file = file.path(tif_path, tif_list[i])
  # Do not assume that the list of files are exactly equivalent.
  # Instead create CSV file name from tif file
  csv_name = gsub("tif", "csv", tif_file)
  csv_file = file.path(csv_path, csv_name)
  r = rast(tif_file)
  csv_df = read.csv(csv_file)
  # Assume csv long/lat are the same CRS as the tif files
  pts = vect(csv_df, geom=c("long", "lat"), crs=st_crs(tif)) 
  result = extract(r, pts, xy = TRUE)
  new_csv = paste0(tools::file_path_sans_ext(csv_file),"_chloro.csv")
  write.csv(result, file.path(csv_path, new_csv))
  return(result)
  })