如何使用Lapply批量处理R中的geoTIFF [英] How to batch process geoTIFFs in R with lapply

查看:110
本文介绍了如何使用Lapply批量处理R中的geoTIFF的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些较大的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...一样并行地循环遍历rf,这可以通过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(),因为我们需要调用该函数以产生副作用.这会循环遍历rf,因此您可以传递一个作为要写入的对象,传递一个作为文件名.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆