4

I have a set of rasters. I crop them all using FOR loop. Then, I want to save new-created rasters in new directory, not in my actual directory. For one raster it is easy:

writeRaster(raster1, filename="raster1.img", format="HFA", overwrite=TRUE)

script for my loops:

# read files
setwd("D:/Data/LANDSAT")
library(raster)
library(rgdal)

# read files containing n_msi...
raster_data<-list.files(path=getwd(), pattern="n_msi.*.img$")   
a<-raster("a.img")

# create a list object containing raster objects
rast.list<-list()
for(i in 1:length(raster_data)){
rast.list[i] <-raster(raster_data[i])}

# get extent of smaller raster
e<-extent(a)

# crop larger raster to smaller raster  - it create rectangle object
crop.list<-list()
for(i in 1:length(rast.list)){
crop.list[[i]]<-crop(rast.list[[i]], e)}

# get rasters names 
rst.names<-c(1:length(rast.list))
for(i in 1:length(rast.list)){
rst.names1<-names(rast.list[[i]])
rst.names[[i]]<-rst.names1}

# write raster data 
mapply(writeRaster, crop.list, new.rst.names, 'HFA')  

Please, how to write "mapply" to save rasters in new directory? or, how to loop it with "writeRasters"?

2
  • Do your .img files all have the same extent and resolution to begin with?
    – jbaums
    Jan 21, 2015 at 17:11
  • yeah, they have all the same resolution and the same extent
    – maycca
    Jan 22, 2015 at 9:33

3 Answers 3

6

This is almost a duplicate of this post, but you have an additional cropping step, so I'll post a new solution.

Given your .img files all have identical extent and resolution, you can save a lot of hassle by stacking them from the start (you can pass a vector of file names to raster::stack). You can then crop the stack in one shot, and write them all out together as well.

Three lines of code:

s <- stack(list.files(path=getwd(), pattern='n_msi.*\\.img$'))
s.crop <- crop(s, raster('a.img'))
writeRaster(s.crop, file.path('~/../Desktop/', names(s)), bylayer=TRUE, driver='HFA')

Change the path as required. The files will be given their imported names (usually the file names that were read in, but you can check this with names(s.crop)), and will be written to the path specified in file.path(...).

2
  • Thank you very much @jbaums! I wasn´t really sure where to put file.path('~/../Desktop/' but now it works great ! :-)
    – maycca
    Jan 22, 2015 at 13:39
  • Much better than the previous way I was doing this! Thanks! Nov 21, 2018 at 0:58
5

jbaums solution is good, but in cases where you cannot make a stack you can do something like the below. Just a single loop (not three or four!). Pau's solution (first making a table) is needlessly complex, and involves too much manual labor, and cannot be easily applied to other datasets.

# read files
setwd("D:/Data/LANDSAT")
library(raster)
library(rgdal)

a <- raster("a.img")
e <- extent(a)

outpath <- "d:/data/landsatcrop/"
dir.create(outpath)

files <- list.files(pattern="n_msi.*.img$")   

# add output directory
outfiles <- paste0(outpath, files)
# change extensions
extension(outfiles) <- 'hfa'

for(i in 1:length(files)) {
    r <-raster(files[i])
    rc <- crop(r, e)
    rc <- writeRaster(rc, outfiles[i])
}
0
0

I recommend you create a table (excel, txt, csv, etc) with the name of the raster you want to process and the folder where you want to save the output raster in different columns. You can use this script:

#load library
library(raster)
library(rgdal)
#
#read table
TABLE=as.data.frame(read.table("D:/table.csv", sep=";", header=T))

#initial value
id=0

#iteration
while (id<(max(TABLE[,1])+1)) {
id=id+1
#        
#select image
for(i in 1:length(TABLE[,1])) {if (TABLE[i,1]==id) {IMAGE=TABLE[i,2]}}
#
#output folder
for(i in 1:length(TABLE[,1])) {if (TABLE[i,1]==id) {OUTPUT=TABLE[i,3]}}
#
#write raster
writeRaster(IMAGE, OUTPUT, format="HFA",overwrite=TRUE)
}

you can add your process inside the script

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.