How to change the resolution of a raster layer in R
You can use aggregate or disaggregate.
library(raster)
#get some sample data
data(meuse.grid)
gridded(meuse.grid) <- ~x+y
meuse.raster <- raster(meuse.grid)
res(meuse.raster)
#[1] 40 40
#aggregate from 40x40 resolution to 120x120 (factor = 3)
meuse.raster.aggregate <- aggregate(meuse.raster, fact=3)
res(meuse.raster.aggregate)
#[1] 120 120
#disaggregate from 40x40 resolution to 10x10 (factor = 4)
meuse.raster.disaggregate <- disaggregate(meuse.raster, fact=4)
res(meuse.raster.disaggregate)
#[1] 10 10
How to change resolution of 2 rasters layers in R?
Here is a self-contained, minimal, reproducible example:
library(raster)
bioclim <- raster(nrow=163, ncol=319, ext=extent(18.83337, 72.00005, 40.99999, 68.16666))
soil <- raster(nrow=1256, ncol=2213, ext=extent(20, 69.99999, 42.62224, 71))
values(soil) = 1:ncell(soil)
Solution: if you cannot use (dis-)aggregate
, you can use resample
sb <- resample(soil, bioclim)
sb
#class : RasterLayer
#dimensions : 163, 319, 51997 (nrow, ncol, ncell)
#resolution : 0.1666667, 0.1666667 (x, y)
#extent : 18.83337, 72.00005, 40.99999, 68.16666 (xmin, xmax, ymin, ymax)
#crs : +proj=longlat +datum=WGS84 +no_defs
#source : memory
#names : layer
#values : 284578.3, 2779484 (min, max)
Or use terra
, if you need better performance:
library(terra)
bc <- rast(nrow=163, ncol=319, ext=ext(18.83337, 72.00005, 40.99999, 68.16666))
so <- rast(nrow=1256, ncol=2213, ext=ext(20, 69.99999, 42.62224, 71))
values(so) = 1:ncell(so)
sb <- resample(so, bc)
How does R assign a resolution to raster objects?
From what I understand from the vignette
The default settings will create a global raster data structure with a longitude/latitude coordinate reference system and 1 by 1 degree cells.
r
# class : RasterLayer
# dimensions : 18, 18, 324 (nrow, ncol, ncell)
# resolution : 20, 10 (x, y)
# extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
# coord. ref. : +proj=longlat +datum=WGS84
r
x extent goes to from -180 to +180 degrees by default (a total of 360 degrees), and 360 degrees / 18 points = a x resolution of 20 degrees.
r
y extent goes form -90 to +90 degrees by default, and 180 degrees / 18 points results in a y resolution of 10 degrees.
Matching the resolution of two rasters
Why would this Error: !is.null(fact) is not TRUE
be odd? If you look at ?disaggregate
you will see that there is no argument nrows
, but there is a required argument fact
, which you did not supply.
You can do
lc_r2a <- disaggregate (lc_r1, fact=12)
Or
lc_r2b <- disaggregate(lc_r1, fact=12, method='bilinear')
which is equivalent to
lc_r2c <- resample(lc_r1, r)
Why are you not sure that this is correct?
However, given that you want to mask lc_r1
, the logical approach would be to go the opposite direction and change the resolution of your mask, r
,
ra <- aggregate(r, fact=12, na.rm=TRUE)
lcm <- mask(lc_r1, ra)
Resample raster
r_hr <- raster(nrow=70, ncol=70) #High resolution raster with categorical data
set.seed(0)
r_hr[] <- round(runif(1:ncell(r_hr), 1, 5))
r_lr <- raster(nrow=6, ncol=6)
r_hr
#class : RasterLayer
#dimensions : 70, 70, 4900 (nrow, ncol, ncell)
#resolution : 5.142857, 2.571429 (x, y)
#extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
#coord. ref. : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
#data source : in memory
#names : layer
#values : 1, 5 (min, max)
r_lr
#class : RasterLayer
#dimensions : 6, 6, 36 (nrow, ncol, ncell)
#resolution : 60, 30 (x, y)
#extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
#coord. ref. : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
Direct aggregate is not possible, because 70/6 is not an integer.
dim(r_hr)[1:2] / dim(r_lr)[1:2]
#[1] 11.66667 11.66667
Nearest neighbor resampling is not a good idea either as the results would be arbitrary.
Here is a by layer approach that you suggested and dww also showed already.
b <- layerize(r_hr)
fact <- round(dim(r_hr)[1:2] / dim(r_lr)[1:2])
a <- aggregate(b, fact)
x <- resample(a, r_lr)
Now you have proportions. If you want a single class you could do
y <- which.max(x)
In that case, another approach would be to aggregate the classes
ag <- aggregate(r_hr, fact, modal)
agx <- resample(ag, r_lr, method='ngb')
Note that agx
and y
are the same. But they can both be problematic as you might have cells with 5 classes with each about 20%, making it rather unreasonable to pick one winner.
Aggregate large raster to raster with lower resolution via mean (R)
The ratio of your resolutions turns out to be an exact integer:
res1 = 0.9/(60*60) # resolution converted to degrees
res2 = 0.5
res.factor = res2 / res1
res.factor
# [1] 2000
You can double check this with you actual rasters using res.factor = res(forest1) / res(dfr_2010_crop)
- I can't do that because you did not provide a reproducible example.
This means that you can simply use raster::aggregate to change the resolution.
TreeCoverPercent = aggregate(forest1, res.factor)
In case your res.factor was not a precise integer, then you can still use this method by rounding to the nearest integer, followed by resampling to the final desired resolution.
TreeCoverPercent = aggregate(forest1, round(res.factor))
TreeCoverPercent = resample(TreeCoverPercent, dfr_2010_crop)
Related Topics
How to Increase the Size of Points in Legend of Ggplot2
How to Combine Multiple Ggplot2 Elements into the Return of a Function
Reading Hdf Files into R and Converting Them to Geotiff Rasters
Namespace Dependencies Not Required
Convert Matrix to Three Column Data.Frame
In R, How to Subset a Data.Frame by Values from Another Data.Frame
Matching Multiple Columns on Different Data Frames and Getting Other Column as Result
How to Compute Correlations Between All Columns in R and Detect Highly Correlated Variables
Knitr (R) - How Not to Embed Images in the HTML File
Display Y-Axis for Each Subplot When Faceting
What Is a Good Way to Read Line-By-Line in R
How to Annotate() Ggplot with Latex
Marking Specific Tiles in Geom_Tile()/Geom_Raster()
Create a Formula in a Data.Table Environment in R
Apply Function to Each Column in a Data Frame Observing Each Columns Existing Data Type