How to batch process geoTIFFs in R with lapply

余生颓废 提交于 2019-12-04 17:12:31
Phil

I think you were basically nearly there, with two corrections:

First, you're calling writeRaster for its side effects (i.e. its ability to write a file to your filesystem) so you don't need to assign the output of your lapply() loop to an object. So, removing a <- we have:

lapply(r, writeRaster, filename = paste0(f, ".asc"), format = "ascii")

Next, the filename argument won't loop through f in this way. You have two options, of which the simplest is probably to pass the @file@name slot of r to the filename argument using an anonymous function:

lapply(r, function(x) {
  writeRaster(x, filename = x@file@name, format = "ascii", overwrite = TRUE)
})

Your other option would be to loop through r and f in parallel like you can in python with for r, f in..., which can be done with purrr:

library("purrr")
walk2(r, f, function(x, y) {
  writeRaster(x = x, filename = y, format = "ascii")
})

Here we're using walk2() rather than map2() because we need to call the function for side effects. This loops through r and f together so you can pass one to be the object to write, and one to be the filename.


Edit: here's the code I use to reproduce the problem

library("raster")

tmp_dir = tempdir()
tmp     = tempfile(tmpdir = tmp_dir, fileext = ".zip")

download.file(
  "http://biogeo.ucdavis.edu/data/climate/cmip5/10m/cc26bi50.zip",
  destfile = tmp
)
unzip(tmp, exdir = tmp_dir)

f = list.files(tmp_dir, pattern = ".tif$", full.names = TRUE)
r = lapply(f, raster)

# Solution one
lapply(r, function(x) {
  writeRaster(x, filename = x@file@name, format = "ascii", overwrite = TRUE)
})

# solution two
library("purrr")
walk2(r, f, function(x, y) {
  writeRaster(x = x, filename = y, format = "ascii")
})

To test how to do this with small files:

library(raster)
s <- stack(system.file("external/rlogo.grd", package="raster")) 
writeRaster(s, file='testtif', format='GTiff', bylayer=T, overwrite=T)
f <- list.files(pattern="testtif_..tif")

Now you can use f with Phil's nice examples. You can also combine all in one step lapply:

f <- list.files("inputFolder", pattern = "*.tif", full.names = TRUE)
r <- lapply(f, function(i) { writeRaster(raster(i), filename=extension(i, '.asc'), overwrite=TRUE)} )

But if you have trouble with lapply, write a loop (it is fine!):

for (i in 1:length(f)) {
   r <- raster(f[i])
   ff <- extension(f[i], '.asc')
   writeRaster(r, ff)
}

Or like this

for (file in f) {
   r <- raster(file)
   ff <- extension(file, '.asc')
   writeRaster(r, ff)
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!