如何使用Lapply批量处理R中的geoTIFF [英] How to batch process geoTIFFs in R with lapply
问题描述
我有一些较大的geoTIFF,现在我想将它们转换为ASCII文件,在进行一些搜索之后,我编写以下代码:
I have some large geoTIFFs, now I want to convert them to ASCII files, after doing some searches, I write these codes:
library(raster)
f <- list.files("inputFolder", pattern = "*.tif", full.names = TRUE)
r <- lapply(f, raster)
a <- lapply(r, writeRaster, filename = "output", format = "ascii")
让我感到困惑的是,如何根据原始名称分别命名输出文件?
What confused me is that how can I name the output files respectively, according to its original names?
我尝试过:
a <- lapply(r, writeRaster, filename = "outputFolder" + f, format = "ascii")
但是我收到了错误消息:
But I received error:
二进制运算符的非数字参数
non-numeric argument to binary operator
然后我尝试:
a <- lapply(r, writeRaster, filename = paste0(f, ".asc"), format = "ascii")
但是我收到了:
文件(文件名,"w")中的错误:无效的'description'参数 另外:警告消息:1:在if(filename =="){: 条件的长度> 1,并且仅使用第一个元素2: if(!file.exists(dirname(filename))){:条件的长度> 1,并且仅使用第一个元素3:如果 (toupper(x @ file @ name)== toupper(filename)){:条件为 长度> 1,并且仅会使用第一个元素4:如果 (trim(filename)=="){:条件的长度> 1,并且只有 第一个元素将被使用5:在if(!file.exists(dirname(filename)))中 {:条件的长度> 1,只有第一个元素是 使用6:在if(filename =="){中:条件的长度> 1且 仅使用第一个元素7:在if(!overwrite& file.exists(filename)){:条件的长度> 1,并且仅 将使用第一个元素
Error in file(filename, "w") : invalid 'description' argument In addition: Warning messages: 1: In if (filename == "") { : the condition has length > 1 and only the first element will be used 2: In if (!file.exists(dirname(filename))) { : the condition has length > 1 and only the first element will be used 3: In if (toupper(x@file@name) == toupper(filename)) { : the condition has length > 1 and only the first element will be used 4: In if (trim(filename) == "") { : the condition has length > 1 and only the first element will be used 5: In if (!file.exists(dirname(filename))) { : the condition has length > 1 and only the first element will be used 6: In if (filename == "") { : the condition has length > 1 and only the first element will be used 7: In if (!overwrite & file.exists(filename)) { : the condition has length > 1 and only the first element will be used
推荐答案
我认为您基本上已经到了,并且进行了两项更正:
I think you were basically nearly there, with two corrections:
首先,您要调用writeRaster
的副作用(即它可以将文件写入文件系统的能力),因此无需将lapply()
循环的输出分配给对象.因此,删除a <-
我们有:
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")
接下来,filename
参数将不会以这种方式在f
中循环.您有两个选择,其中最简单的选择可能是使用匿名函数将r
的@file@name
插槽传递给filename
参数:
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)
})
您的另一个选择是像在python中使用for r, f in...
一样并行地循环遍历r
和f
,这可以通过purrr
完成:
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")
})
在这里,我们使用的是walk2()
而不是map2()
,因为我们需要调用该函数以产生副作用.这会循环遍历r
和f
,因此您可以传递一个作为要写入的对象,传递一个作为文件名.
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.
这是我用来重现该问题的代码
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")
})
这篇关于如何使用Lapply批量处理R中的geoTIFF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!