# Changing extent of raster in loop using R

I have raster objects of a certain extent (0, 360, -90, 90) and I want to change that extent for all of them to a different extent (-180, 180, -90, 90). The thing is that I have my objects (raster layers) in a list and I want to change the extent with one step in a loop.

My approach (example)

``````st_ext <- extent(-180, 180, -90, 90)

for (i in 1:NROW(r)){
r[[i]] <- setExtent(r[[i]], st_ext)
}
``````

When I do it like this, the extent does not change but when I use the exact same command where I put in "i" manually, the extent changes like it should.

``````r[[1]] <- setExtent(r[[1]], st_ext)
``````

Why does this happen and how I can make it work with the loop?

I also tried

``````extent(r[[i]]) <- st_ext
``````

and

``````xmin(r[[i]]) <- -180
xmax(r[[i]]) <- 180
``````

But when using all of those those in a loop, the extent remains unchanged.

• Perhapse try `1:length(r)` rather than `NROW` Apr 1, 2021 at 22:13

Although not directly answering your question, I think it is important to point out that if you want to change the extent of raster `x` from `(0, 360, -90, 90)` to `(-180, 180, -90, 90)` you should use `rotate(x)`, not `setExtent`.

The loop should work as Spacedman shows. Can you make an example where it does not? It seems clear that your problem originates earlier on --- you say you used `mget` which is always the wrong approach.

You also say that the object names contain a `-`. Do you mean the layer names? R object names cannot contain the minus sign, for obvious reasons. (well unless you backtick them as in `a-b`, but how much self-inflicted pain are you willing to suffer?)

Can't you use a RasterStack?

• I used the mget function because I wanted to have all objects in a list (or whatever) that match a certain pattern in one place. The "-" does not matter in that case as I never refer to these objects by their names but only when addressed to in the list. Just in case, I replaced it with "_" to resolve any problems that could originate here. However, that didn't change the loop problem. I found a feasible solution (see Answer below) using a RasterStack and no loop. Apr 6, 2021 at 11:40

Are you sure your `r` is a list? This works for me:

I'm going to set the extents the other way round from you, but that doesn't matter:

``````> st_ext <- extent(0, 360, -90, 90)
``````

which I'm doing because the simplest way of making a raster sets the extent to -180:180:

``````> v = raster()
> extent(v)
class      : Extent
xmin       : -180
xmax       : 180
ymin       : -90
ymax       : 90
``````

Now make a list of them:

``````> r = list(v,v,v,v)
``````

Check the first one:

``````> extent(r[[1]])
class      : Extent
xmin       : -180
xmax       : 180
ymin       : -90
ymax       : 90
``````

Now loop and set new extent:

``````> for(i in 1:4){
r[[i]] = setExtent(r[[i]], st_ext)
}
``````

And they've changed:

``````> extent(r[[1]])
class      : Extent
xmin       : 0
xmax       : 360
ymin       : -90
ymax       : 90
``````

Are you sure your `r` is a list of rasters?

• Yes it is a (class) list containing raster layer objects (large lists and large raster layers to be precise). I created the lists in question with the mget function. The names of the raster layer objects contain a "-" which is the only 'odd' thing here I could think of.. Apr 1, 2021 at 21:34

No matter what combination of commands I tried it didn't appear to work with a loop. However, the other answers helped me to find a workaround.

A little more background information: I am working with multiple datasets and the mget function helped me organize the objects I use in a list. These lists can also be made into RasterStacks with little effort. In the code I worked out below, I make a list out of the lists I created. Each list is then made into a RasterStack as I rotate that whole RasterStack.

``````listP_m <- mget(ls(pattern="^P_.*mean\$"))

listF1rcp26m <- mget(ls(pattern="^F1rcp26.*mean\$"))
listF2rcp26m <- mget(ls(pattern="^F2rcp26.*mean\$"))

listF1rcp60m <- mget(ls(pattern="^F1rcp60.*mean\$"))
listF2rcp60m <- mget(ls(pattern="^F2rcp60.*mean\$"))

listALL_m <- mget(ls(pattern="^list.*m\$"))

for (i in 1:NROW(listALL_m)){
for (j in 1:NROW(listALL_m[[i]])){
if(length(listALL_m[[i]])>0){
assign(names(listALL_m[i]), rotate(stack(listALL_m[[i]])))
}
}}
``````

There are easier ways, I know, but this approach gave the desired solution with the least amount of effort required in changing my code.

• If you need to use mget and assign you make a mistake earlier on. The mistake you make is not having your objects in a list or RasterStack in the first place. Apr 6, 2021 at 16:22

Hi I found this solution which worked for me.

set the path to the folder where all raster files are (for me its a test folder in desktop)

path <- file.path("C:/Desktop/test")

load all raster files in r (my files are in .tif format)

rastlist <- list.files(path, pattern='tif\$', all.files=TRUE, full.names=FALSE)

create a list of raster (I think this is the part missing in OP's problem)

r <- lapply(rastlist, raster)

define the required extent for all files

st_ext <- extent(-180, 180, -90, 90)

create a loop to set new extent

for (i in 1:NROW(r)){ r[[i]] <- setExtent(r[[i]], st_ext) }

check the extent of some rasters to see if it worked or not as required

extent(files[[1]])

extent(files[[3]])

......