【问题标题】:saving and naming files in R automatically based on input filename根据输入文件名在 R 中自动保存和命名文件
【发布时间】:2020-09-20 21:42:19
【问题描述】:

我已经使用 AdehabitatHR 生成了几个利用率分布 (UD),并将它们存储为 Geotiff。我现在使用与 Lattice 包相同的 UD 来生成一些地图并将它们保存到具有 LZW 压缩的高分辨率 tiff 图像。问题是我实际上有数百张地图要制作、保存和命名。一旦我从目录中加载了所有必要的文件,有没有办法自动执行此操作?我的每个 UD 都具有以下文件名结构“UD_resolution_species_area_year_season.tif”,在我给地图的最终名称中,我想保持相同的结构(或整个文件名),但添加前缀“blablabla_”,例如“blablabla_UD_resolution_species_area_year_season.tiff”。图像还包括一个主要名称,一个大写字母,它也应该改变。

目前我正在使用以下内容:

rlist = list.files(getwd(), pattern = "tif$", full.names = FALSE)
for (i in rlist) {
  assign(unlist(strsplit(i, "[.]"))[1], raster(i))
}

 shplist = list.files(getwd(), pattern = "shp$", full.names = FALSE)
for (i in shplist) {
  assign(unlist(strsplit(i, "[.]"))[1], readOGR(i))
}

UD <- 'UD_resolution_species_area_year_season'
    ext <- extent(UD) + 0.3 # set the extent for the plot

    aa <-
      quantile(UD,
               probs = c(0.25, 0.75),
               type = 8,
               names = TRUE)
    my.at <- c(aa[1], aa[2])
    my.at <- round(my.at, 3)

    maxval <- maxValue(UD)

tiff(
  "C:/myworkingdirectory/maps/blablabla_UD_resolution_species_area_year_season.tiff",
  res = 600,
  compression = "lzw",
  width = 15,
  height = 15,
  units = "cm"
)

levelplot(
  UD,
  xlab = "",
  ylab = "",
  xlim = c(ext[1], ext[2]),
  ylim = c(ext[3], ext[4]),
  margin = FALSE,
  contour = FALSE,
  col.regions = viridis(1000),
  colorkey = list(at = seq(0, maxval)),
  main = "A",
  maxpixels = 2e5
) + latticeExtra::layer(sp.polygons(Land, fill = "grey50", col = NA)) + contourplot(
  `UD`,
  at = my.at[1],
  labels = FALSE,
  margin = FALSE,
  lty = 2,
  col = "orange",
  pretty = TRUE
) + contourplot(
  UD,
  at = my.at[2],
  labels = FALSE,
  margin = FALSE,
  lty = 2,
  col = "red",
  pretty = TRUE,
)

dev.off()

【问题讨论】:

    标签: r plot lattice levelplot


    【解决方案1】:

    使用assign 是初学者的常见错误。不要不要使用它,它会造成您现在面临的麻烦。相反,您可以制作列表和/或使用循环。

    您还问的是基本的 R 内容,但是您通过添加许多有关设置范围和水平图的不相关细节使问题复杂化。最好通过消除混乱并首先关注一个简​​单的案例来学习做这些基本的事情。这也是你应该为这个论坛写问题的方式。

    本质上,您有一堆要处理的文件。下面我将展示如何循环遍历名称向量,然后循环并在该循环中执行您需要执行的操作。

    library(raster)
    rastfiles <- list.files(pattern = "tif$", full.names=TRUE)
    outputfiles <- file.path("output/path", paste0("prefix_", basename(rastfiles)))
    for (i in 1:length(rastfiles))    
       r <- raster(rastfiles[i])
       png(outputfiles[i])
       plot(r)
       dev.off()
     }
    

    也可以先将所有文件读入一个列表

    rastfiles <- list.files(pattern = "tif$", full.names=TRUE)
    rlist <- lapply(rastfiles, raster)
    names(rlist) <- gsub(".tif$", "", basename(rastfiles))
    
    rastfiles <- list.files(pattern = "shp$", full.names=TRUE)
    slist <- lapply(shpfiles, readOGR)
    names(slist) <- gsub(".shp$", "", basename(shpfiles))
    

    也许还可以创建一个输出文件名向量

    outputtif <- file.path("output/dir", basename(rastfiles))   
    

    然后遍历列表中的项目,或者输出文件名

    【讨论】:

    • 谢谢罗伯特。我经常问和阅读答案“......提供详细信息......”的问题。作为 Lattice 的新手,我认为该包有一些基本 R 函数的替代方案。我已经根据我的需要修改了循环,但是在正确生成了一些映射后,我得到以下信息:错误:$ 运算符对原子向量无效此外:警告消息:1:在 min(x) 中:没有非缺失参数至分钟;返回 Inf 2:在 max(x) 中:max 没有非缺失参数;返回 -Inf 此外,我应该使用 print(levelplot()) 还是 plot(levelplot())?
    • 不用担心,但要让本网站正常运行,以最佳方式提出问题很重要。你的附加问题说明了我的观点。一次问一个问题很重要。在这种情况下,将 (a) 使用文件名和循环的问题与 (b) 在循环中使用 levelplot 分开。对于 (b),您可以提出一个新问题并包含一些示例数据(例如,来自 levelplot、spplot 或 rasterVis 的帮助文件)。在许多情况下,只需编写该问题即可让它自己回答。如果没有,您可以访问此站点,它可能会对您和其他许多人有所帮助。
    猜你喜欢
    • 2015-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-14
    • 2016-03-29
    • 1970-01-01
    相关资源
    最近更新 更多