1

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.

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

4 Answers 4

1

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?

1
  • 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.
    – Ferdi
    Apr 6, 2021 at 11:40
1

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?

1
  • 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..
    – Ferdi
    Apr 1, 2021 at 21:34
0

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.

1
  • 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
0

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]])

......

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.