I am trying to align .asc rasters with different extents but same resolution in R so that they can be used to create a Raster stack. I am working with the "raster" package (Hijmans et al. 2022, version 3.5-29)
The rasters have the following properties:
> r1;r2
class : RasterLayer
dimensions : 1420, 1207, 1713940 (nrow, ncol, ncell)
resolution : 50, 50 (x, y)
extent : -30155.19, 30194.81, -35519.03, 35480.97 (xmin, xmax, ymin, ymax)
crs : NA
source : Naive_IS2018_UDScaled.asc
names : Naive_IS2018_UDScaled
class : RasterLayer
dimensions : 1418, 939, 1331502 (nrow, ncol, ncell)
resolution : 50, 50 (x, y)
extent : -23488.8, 23461.2, -35475.82, 35424.18 (xmin, xmax, ymin, ymax)
crs : NA
source : Naive_IS2019_UDScaled.asc
names : Naive_IS2019_UDScaled
In order to bring them to the same extent, I am creating a raster list and extract the minimum and maximum values:
## align all rasters to same extent
rasterlist <- as.list(r1,r2)
raster_extents <- lapply(rasterlist, raster::extent)
do.call(raster::merge, raster_extents)
sharedextent <- c(-30155.19 , 30194.81 , -35519.03 , 35480.97)
Now I am using the enxtend() to extend the extents of the rasters so that they share the same extents.
r1 <- raster::extend(r1, sharedextent)
r2 <- raster::extend(r2, sharedextent)
However, this does not result in a change of extents. But, it changes the source to "memory" and add a "values" row in r2.
> r1;r2
class : RasterLayer
dimensions : 1420, 1207, 1713940 (nrow, ncol, ncell)
resolution : 50, 50 (x, y)
extent : -30155.19, 30194.81, -35519.03, 35480.97 (xmin, xmax, ymin, ymax)
crs : NA
source : Naive_IS2018_UDScaled.asc
names : Naive_IS2018_UDScaled
class : RasterLayer
dimensions : 1420, 1207, 1713940 (nrow, ncol, ncell)
resolution : 50, 50 (x, y)
extent : -30138.8, 30211.2, -35525.82, 35474.18 (xmin, xmax, ymin, ymax)
crs : NA
source : memory
names : Naive_IS2019_UDScaled
values : 0, 0.0006528347 (min, max)
Any help would be greatly appreciated.
Is that you are looking for? (Updated with keepres = TRUE). Please keep in mind that changing extent will either change resolution, either number of rows/columns.
library(raster)
#> Loading required package: sp
r1 <- raster(nrows = 1420, ncols = 1207, resolution = 50, ext = extent(c(-30155.19, 30194.81, -35519.03, 35480.97)))
r2 <- raster(nrows = 1418, ncols = 939, resolution = 50, ext = extent(c(-23488.8, 23461.2, -35475.82, 35424.18)))
r2
#> class : RasterLayer
#> dimensions : 1418, 939, 1331502 (nrow, ncol, ncell)
#> resolution : 50, 50 (x, y)
#> extent : -23488.8, 23461.2, -35475.82, 35424.18 (xmin, xmax, ymin, ymax)
#> crs : NA
r2 <- setExtent(r2, r1, keepres=TRUE)
r2
#> class : RasterLayer
#> dimensions : 1420, 1207, 1713940 (nrow, ncol, ncell)
#> resolution : 50, 50 (x, y)
#> extent : -30155.19, 30194.81, -35519.03, 35480.97 (xmin, xmax, ymin, ymax)
#> crs : NA
Created on 2022-09-06 with reprex v2.0.2
Related
I have two raster:
raster1
class : SpatRaster
dimensions : 21600, 43200, 1 (nrow, ncol, nlyr)
resolution : 0.008333333, 0.008333333 (x, y)
extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
raster2
class : SpatRaster
dimensions : 720, 1440, 1 (nrow, ncol, nlyr)
resolution : 0.25, 0.25 (x, y)
extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
coord. ref. : lon/lat WGS 84
I want to run zonal stastics to calculate sum of smaller raster raster1 on bigger raster raster2:
terra::zonal(raster1, raster2, fun = sum, as.raster=T, filename = 'zonal.tif')
Error: [zonal] dimensions and/or extent do not match
I wasn't sure why the extent are not matching until I did this
terra::ext(raster1)
SpatExtent : -180.000001017276, 180.000001017276, -90.0000010172997, 90.0000010172997 (xmin, xmax, ymin, ymax)
terra::ext(raster2)
SpatExtent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
which shows that raster1 extent have some imprecision. What are different ways I can fix this?
EDIT: I tried the suggestion in the comment
terra::crs(raster2) <- sf::st_crs(4326)$wkt
terra::crs(raster1) <- sf::st_crs(4326)$wkt
terra::ext(raster2)
SpatExtent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
terra::ext(raster1)
SpatExtent : -180.000001017276, 180.000001017276, -90.0000010172997, 90.0000010172997 (xmin, xmax, ymin, ymax)
But my extent are still not matching
The error message is
Error: [zonal] dimensions and/or extent do not match
In this case, that clearly refers to the difference is dimensions, which are
#dimensions : 21600, 43200, 1 (nrow, ncol, nlyr)
#dimensions : 720, 1440, 1 (nrow, ncol, nlyr)
I do not think the small difference in the extent is relevant at all.
To make the dimensions match you can use disagg or aggregate with a factor of 30.
If the crs of raster2 is different from that of raster1 you can (in this case, where you clearly have two global lon/lat rasters) fix that with
crs(raster2) <- crs(raster1)
And for good measure, you could in this case also do
ext(raster2) <- ext(raster1)
Mismatching extents don't stop zonal working, so I think that error message is wrong. Here's two rasters that only differ in their CRS:
> library(terra)
terra 1.5.21
> raster1 = rast()
> raster1[]=1:360
> raster2 = rast()
> raster2[]=1:360
> crs(raster1) = ""
> zonal(raster1, raster2)
Error: [zonal] dimensions and/or extent do not match
I guess it could be argued that a different CRS means a different extent in the same way that "23" is different to "23 km". But the extent and the dimensions are all the same according to these tests:
> ext(raster1) == ext(raster2)
[1] TRUE
> dim(raster1) == dim(raster2)
[1] TRUE TRUE TRUE
Rasters with a different extent work fine with zonal (once I've set the CRSs to match):
> ext(raster2) = c(-180.01, 180.01, -90.01, 90.01)
> crs(raster2) = ""
> z = zonal(raster1, raster2)
>
If you do want to change an extent, you can use ext(r) = ... as above, but you should try and figure out why extents don't match. Likely its because you have data on points and you may have cells extending out from points...
I am trying to disaggregate a raster using terra package. My original raster is:
library(terra)
my_raster
class : SpatRaster
dimensions : 180, 360, 1 (nrow, ncol, nlyr)
resolution : 1, 1 (x, y)
extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
coord. ref. : lon/lat WGS 84
source : EHF2_2020_max.nc_rotated.nc
varname : X2020
name : X2020
I want to drop the resolution to the following target raster
target_raster
class : SpatRaster
dimensions : 21600, 43200, 1 (nrow, ncol, nlyr)
resolution : 0.008333333, 0.008333333 (x, y)
extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
coord. ref. : lon/lat WGS 84
source : GDP_PPP_30arcsec_v3.nc
varname : GDP_PPP (Gross Domestic Production (GDP) (PPP))
name : GDP_PPP_3
unit : constant 2011 international US dollar
When I did this, I get below error:
disagg_raster <- disagg(my_raster, fact = c(21600,43200))
Error: [disagg] insufficient disk space (perhaps from temporary files?)
I have a fresh R session and other than these two objects, nothing else is loaded in my environment. What is causing this error?
However, when I disaggregate raster using resample, I do not get any memory issue
resample_raster <- resample(my_raster, target_raster, method='bilinear')
I get below error:
disagg_raster <- disagg(my_raster, fact = c(21600,43200))
# Error: [disagg] insufficient disk space (perhaps from temporary files?)
That says there is not enough disk space to write the file. Output SpatRasters are are written to disk if they are deemed too large to keep in memory. As you do not provide a filename argument, the file would go to the tempdir() folder and that does not have enough disk space.
This is happening because you use trying to create a monster of a raster (easy to do and see for a raster that has no cell values):
library(terra)
r <- rast()
disagg(r, fact = c(21600,43200))
#class : SpatRaster
#dimensions : 3888000, 15552000, 1 (nrow, ncol, nlyr)
#resolution : 2.314815e-05, 4.62963e-05 (x, y)
#extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
#coord. ref. : lon/lat WGS 84
It appears that you misunderstood the fact argument. To get the spatial resolution of your target raster you can do:
disagg(r, fact = 120)
#class : SpatRaster
#dimensions : 21600, 43200, 1 (nrow, ncol, nlyr)
#resolution : 0.008333333, 0.008333333 (x, y)
#extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
#coord. ref. : lon/lat WGS 84
That is still big enough, but it should not create problems.
This is my raster properties:
class : RasterLayer
dimensions : 3001, 3000, 9003000 (nrow, ncol, ncell)
resolution : 0.12, 0.034 (x, y)
extent : -180, 180, -40.034, 62 (xmin, xmax, ymin, ymax)
crs : +proj=longlat +datum=WGS84 +no_defs
source : test.tif
names : test
I want to convert this into a raster with a resolution of 0.008333333 in both x and y direction
library(raster)
tar_res <- 0.008333333
disagg_raster <- disaggregate(my_raster,
fact = c(res(my_raster)[1]/tar_res, res(my_raster)[2]/tar_res))
disagg_raster
class : RasterLayer
dimensions : 12004, 42000, 504168000 (nrow, ncol, ncell)
resolution : 0.008571429, 0.0085 (x, y)
extent : -180, 180, -40.034, 62 (xmin, xmax, ymin, ymax)
crs : +proj=longlat +datum=WGS84 +no_defs
How do I get the resolution to be 0.008333333 in both x and y direction?
If you cannot get there by (dis) aggregating you can use resample instead.
# example data
library(terra)
r <- rast(nrow=3001, ncol=3000, ymin=-40.034, ymax=62)
# create empty template with the desired geometry
tmp <- rast(r)
res(tmp) <- 1/120
ymax(tmp) <- ymax(r)
# resample
x <- resample(r, tmp)
See here for a more general and longer answer.
I have SpatialPolygonsDataFrame class in R, which I want to rasterize. I rasterize the the polygon using this code below:
> p <- shapefile('MadaGranary')
> p
class : SpatialPolygonsDataFrame
features : 1
extent : 100.1269, 100.5313, 5.793798, 6.446769 (xmin, xmax, ymin, ymax)
crs : +proj=longlat +datum=WGS84 +no_defs
variables : 1
names : id
value : 1
> crs(p) <- NULL
> # Define RasterLayer object
> r.raster <- raster(extent(p), res = 100)
> #rasterize
> p.r <- rasterize(p, r.raster)
> print(p.r)
class : RasterLayer
dimensions : 1, 1, 1 (nrow, ncol, ncell)
resolution : 100, 100 (x, y)
extent : 100.1269, 200.1269, -93.55323, 6.446769 (xmin, xmax, ymin, ymax)
crs : +proj=longlat +datum=WGS84 +no_defs
source : memory
names : layer
values : NA, NA (min, max)
attributes :
ID id
1 1
Unfortunately, this chunk of code has assigned cell dimensions to dimensions : 1, 1, 1 (nrow, ncol, ncell), and its very important for me to get the actual values of ncols and nrows.
And when I print p.r, I need to get the values of dimensions : (nrow, ncol, ncell) in the console so that I will be able to save all attributes in order to use it another analysis later.
attention:The resolutionoutput that I need to get should be real values representing ncols and nrow in the new raster, but not just dimensions : 1, 1, 1 (nrow, ncol, ncell) as shown in my code.
Can any one help please??
If you want to set nrow and ncol then you do so (and not set the resolution, which expresses the size of each cell). Here is an example:
library(raster)
#Loading required package: sp
e <- extent(0,1,0,1)
r <- raster(e, nrow=100, ncol=100)
r
#class : RasterLayer
#dimensions : 100, 100, 10000 (nrow, ncol, ncell)
#resolution : 0.01, 0.01 (x, y)
#extent : 0, 1, 0, 1 (xmin, xmax, ymin, ymax)
#crs : NA
I am trying to calculate the mean of a rasterbrick over specific timesteps in R.
Subsetting the dataset shows a lay-out that appears to be correct (to me), however R does not allow any computations to follow up.
> r_sub <- b[[1699:1862]]
> r_sub
class : RasterStack
dimensions : 127, 147, 18669, 164 (nrow, ncol, ncell, nlayers)
resolution : 5, 5 (x, y)
extent : 603299.4, 604034.4, 6615598, 6616233 (xmin, xmax, ymin, ymax)
crs : NA
names : X2019.02.09.19, X2019.02.09.20, X2019.02.09.21, X2019.02.09.22, X2019.02.09.23, X2019.02.09.24, X2019.02.10.1, X2019.02.10.2, X2019.02.10.3, X2019.02.10.4, X2019.02.10.5, X2019.02.10.6, X2019.02.10.7, X2019.02.10.8, X2019.02.10.9, ...
> r_mean <- calc(r_sub, mean)
Error in Rsx_nc4_get_vara_double: NetCDF: Index exceeds dimension bound
Var: SWIT Ndims: 3 Start: 1698,0,0 Count: 1,127,147
Error in ncvar_get_inner(ncid2use, varid2use, nc$var[[li]]$missval, addOffset, :
C function R_nc4_get_vara_double returned error
How to solve this specific error?
I am guessing that this is related to a problem with your file, not with the code.
I did this and it worked well
library(raster)
b <- brick("filename.nc")
r_sub <- b[[1699:1862]]
r_sub
#class : RasterStack
#dimensions : 160, 320, 51200, 164 (nrow, ncol, ncell, nlayers)
#resolution : 1.125, 1.121277 (x, y)
#extent : -0.5625, 359.4375, -89.70216, 89.70216 (xmin, xmax, ymin, ymax)
#crs : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
mean(r_sub)
#class : RasterLayer
#dimensions : 160, 320, 51200 (nrow, ncol, ncell)
#resolution : 1.125, 1.121277 (x, y)
#extent : -0.5625, 359.4375, -89.70216, 89.70216 (xmin, xmax, ymin, ymax)
#crs : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
#source : memory
#names : layer
#values : 3.033032e-07, 0.0002482847 (min, max)
Also, you might want to look into using stackApply