Suppose one runs the following R code
install.packages("raster")
library(raster)
r <- raster(ncol=18, nrow=18)
res(r)
The output of the res function is
[1] 20 10
How are these values defined? How does the raster function calculate them? In what units are they expressed?
As pointed out by Guillaume Devailly, the horizontal resolution is the horizontal extent divided by the number of columns. The vertical resolution is the vertical extent divided by the number of rows. The units are the units of your coordinate reference system. The default is degrees (for longitude/latitude). To add more to Guillaume's answer:
Create a raster with 10 rows and columns that goes from 0 to 10. The resolution is 1.
library(raster)
r <- raster(ncol=10, nrow=10, xmn=0, xmx=10, ymn=0, ymx=10)
r
#class : RasterLayer
#dimensions : 10, 10, 100 (nrow, ncol, ncell)
#resolution : 1, 1 (x, y)
#extent : 0, 10, 0, 10 (xmin, xmax, ymin, ymax)
#crs : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
Change the resolution to 0.5; the number of rows and columns double
res(r) <- 0.5
r
#class : RasterLayer
#dimensions : 20, 20, 400 (nrow, ncol, ncell)
#resolution : 0.5, 0.5 (x, y)
#extent : 0, 10, 0, 10 (xmin, xmax, ymin, ymax)
#crs : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
You can change the resolution indirectly by adjusting the extent
extent(r) <- c(0,5,0,5)
r
#class : RasterLayer
#dimensions : 20, 20, 400 (nrow, ncol, ncell)
#resolution : 0.25, 0.25 (x, y)
#extent : 0, 5, 0, 5 (xmin, xmax, ymin, ymax)
#crs : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
The x and y resolution can be set to a different value
res(r) <- c(1, 0.5)
When you change the resolution directly, via res any cell values associated with the Raster* object are lost; because the number of rows or columns has to change. If you change it indirectly, by changing the extent, the values stay.
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.
Related
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 a raster of 30m cell size, with either value 0 or 1. I try to aggregate this into a 1000m cell size. I can then see the sum of '1's, in a 1000m cell size raster.
But the Aggregate function only lets me use a round number as a factor, so the closest I get is with factor 33x (to cell size 990m).
I would then need to resample 990m to 1000m but then obviously the values will shift and be incorrect.
Is there a way to use a decimal factor such as 33,3333, or better yet, use a raster with resolution 1000m as a template for the aggregation?
FOR ILLUSTRATION:
Here's an example of one aggregated cell sourced from 30x30m cells with 0/1 values, now in an aggregate raster at 990x990m cell size:
The two original cells are correctly aggregated into a 990x990m cell, and the sum of all values that were of interest (value '1') is 2. You can see these same two cells in the resampled cell on the right, in the top of the cell. But due to the resampling, the raster has shifted and includes more of the 30x30m cells. Yet, the cell value for the now resampled aggregate raster is still 2, while this is an incorrect value and should be 5.
You can use resample.
Example data:
library(terra)
r <- rast(crs="+proj=utm +zone=1", resolution=30, xmin=0, ymin=0, xmax=1020, ymax=1020)
values(r) <- 1:ncell(r)
I first aggregate to a value close to what you want (in this example, I go from 30 to 100 m spatial resolution), and then use resample
a <- aggregate(r, 3, mean)
rr <- rast(crs="+proj=utm +zone=1", resolution=100, xmin=0, ymin=0, xmax=1000, ymax=1000)
b <- resample(r, rr)
r
#class : SpatRaster
#dimensions : 34, 34, 1 (nrow, ncol, nlyr)
#resolution : 30, 30 (x, y)
#extent : 0, 1020, 0, 1020 (xmin, xmax, ymin, ymax)
#coord. ref. : +proj=utm +zone=1 +datum=WGS84 +units=m +no_defs
#source : memory
#name : lyr.1
#min value : 1
#max value : 1156
b
#class : SpatRaster
#dimensions : 10, 10, 1 (nrow, ncol, nlyr)
#resolution : 100, 100 (x, y)
#extent : 0, 1000, 0, 1000 (xmin, xmax, ymin, ymax)
#coord. ref. : +proj=utm +zone=1 +datum=WGS84 +units=m +no_defs
#source : memory
#name : lyr.1
#min value : 68.89777
#max value : 1103.335
You could also first disaggregate and then aggregate. With the above example you could do
d <- disaggregate(r, 3)
da <- aggregate(d, 10)
da
#class : SpatRaster
#dimensions : 11, 11, 1 (nrow, ncol, nlyr)
#resolution : 100, 100 (x, y)
#extent : 0, 1100, -80, 1020 (xmin, xmax, ymin, ymax)
#coord. ref. : +proj=utm +zone=1 +datum=WGS84 +units=m +no_defs
#source : memory
#name : lyr.1
#min value : 43
#max value : 1093
The solution was pretty simple, and I highly suspect the phrasing of my question was just not very clear, apologies for that.
When using the aggregate function (whether it is by mean, sum,...) you cannot resample afterwards and expect the agreggated values to still be correct. The values will be preserved, but because cells shift a little or a lot due to resampling, they will not be correct.
The trick as such, is incredibly simple: resample before you aggregate, not afterwards.
I am using GLASS albedo data stored here for pre-2000 (AVHRR) data and here for post-2000 data (MODIS). My end goal is to create a raster stack of each month that contains white sky albedo data from 1982-2015. The problem I have run into is that the MODIS and AVHRR data are in different spatial reference systems and I can't seem to reproject them to be in the same system.
I convert from hdf to tif using R like this:
fileavhrr <- ".../GLASS02B05.V04.A1990161.2018062.hdf"
filemodis<-".../GLASS02B06.V04.A2013169.2017128.hdf"
gdal_translate(get_subdatasets(filemodis)[10], dst_dataset =
".../modis.tif")
gdal_translate(get_subdatasets(fileavhrr)[8], projwin = c(-180,90,180,50), dst_dataset = ".../avhrr.tif") #ideally I'd only like data north of 50 degrees
avhrr<- raster(".../avhrr.tif")
#class : RasterLayer
#dimensions : 800, 7200, 5760000 (nrow, ncol, ncell)
#resolution : 0.05, 0.05 (x, y)
#extent : -180, 180, 50, 90 (xmin, xmax, ymin, ymax)
#coord. ref. : +proj=longlat +ellps=clrk66 +no_defs
#values : -32768, 32767 (min, max)
modis<- raster(".../modis.tif")
#class : RasterLayer
#dimensions : 3600, 7200, 25920000 (nrow, ncol, ncell)
#resolution : 154.4376, 308.8751 (x, y)
#extent : -20015109, -18903159, 8895604, 10007555 (xmin, xmax, ymin, ymax)
#coord. ref. : +proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181
+b=6371007.181 +units=m +no_defs
#values : -32768, 32767 (min, max)
Here are things I have tried:
1.) Use the MODIS Reprojection Tool. For whatever reason, this tool seems to think the subdatasets of the MODIS .hdf files are only one tile (the upper left most tile, tile 0,0) and not the global dataset. My understanding is that the MODIS data are global (not in tiles?), so I do not know why the MRT is doing this.
2.) Use the raster package in R.
projectedMODIS <- projectRaster(modis,avhrr,method="bilinear")
This returns a raster with values that are all NA:
class : RasterLayer
dimensions : 800, 7200, 5760000 (nrow,> ncol, ncell)
resolution : 0.05, 0.05 (x, y)
extent : -180, 180,> 50, 90 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +ellps=clrk66 +no_defs
values : NA, NA (min, max)
3.) Use the gdalUtils package in R:
gdalwarp(srcfile=get_subdatasets(filemodis)[10], dstfile= ".../gdalMODIS_avhrr.tif", s_srs = crs(modis), t_srs =crs(avhrr) )
This returns a raster with essentially no spatial extent.
gdalMODISavhrr<-raster(".../gdalMODIS_avhrr.tif")
#class : RasterLayer
#dimensions : 357, 12850, 4587450 (nrow, ncol, ncell)
#resolution : 0.02801551, 0.02801573 (x, y)
#extent : -180, 179.9993, 79.99838, 90 (xmin, xmax, ymin, ymax)
#coord. ref. : +proj=longlat +ellps=clrk66 +no_defs
#values : -32768, 32767 (min, max)
Any ideas on why reprojecting this MODIS data is so difficult?
I have not tried this, but from looking at the package gdalUtils, the function gdalwarp() might do what you need?
I have two geotiff raster files, one has all the metadata information and in the other the metadata information was lost. I know that all the metadata information was exactly the same so I want to copy it from one file to the other. I tried to use raster, because I made all the processing in R.
This is the file with metadata
af1_patch <-raster(a_files[6])
af1_patch
class : RasterLayer
dimensions : 38400, 38400, 1474560000 (nrow, ncol, ncell)
resolution : 231.656, 231.656 (x, y)
extent : -2223901, 6671703, -4447802, 4447802 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs
data source : Forest_patches_AF_1.tif
names : Forest_patches_AF_1
values : 0, 255 (min, max)
And this is the file without the metadata
af1_area <-raster(a_files[1])
af1_area
class : RasterLayer
dimensions : 38400, 38400, 1474560000 (nrow, ncol, ncell)
resolution : 1, 1 (x, y)
extent : 0, 38400, 0, 38400 (xmin, xmax, ymin, ymax)
coord. ref. : NA
data source : africa_AF_1.tif
names : africa_AF_1
values : 0, 255 (min, max)
I tried to copy the metadata using:
res(af1_area) <- res(af1_patch)
crs(af1_area) <- crs(af1_patch)
extent(af1_area) <- extent(af1_patch)
but it doesn't work, dimensions and resolution are incorrect and the data values are lost:
af1_area
class : RasterLayer
dimensions : 166, 166, 27556 (nrow, ncol, ncell)
resolution : 53588, 53588 (x, y)
extent : -2223901, 6671703, -4447802, 4447802 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs
hist(af1_area)
Error in .hist1(x, maxpixels = maxpixels, main = main, plot = plot, ...) :
cannot make a histogram; need data on disk or in memory
Thanks!
I think that this is occuring because you are changing the resolution before changeing the extent, because this, the extent is bound by the resolution that you have assigned to it. I was able to reproduce your problem and solve it by changing the order of the process. Hope it works for you!
library(raster)
x <- raster(matrix(1:10))
proj4string(x) <- CRS("+proj=longlat")
extent(x) <- extent(-10,10,-10,10)
y <- raster(matrix(1:10))
z <- raster(matrix(1:10))
#Current Process
res(y) <- res(x)
crs(y) <- crs(x)
extent(y) <- extent(x)
#Working Process
extent(z) <- extent(x)
res(z) <- res(x)
crs(z) <- crs(x)
Output:
> x
class : RasterLayer
dimensions : 10, 1, 10 (nrow, ncol, ncell)
resolution : 20, 2 (x, y)
extent : -10, 10, -10, 10 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +ellps=WGS84
data source : in memory
names : layer
values : 1, 10 (min, max)
> y
class : RasterLayer
dimensions : 1, 1, 1 (nrow, ncol, ncell)
resolution : 20, 20 (x, y)
extent : -10, 10, -10, 10 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +ellps=WGS84
> z
class : RasterLayer
dimensions : 10, 1, 10 (nrow, ncol, ncell)
resolution : 20, 2 (x, y)
extent : -10, 10, -10, 10 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +ellps=WGS84
data source : in memory
names : layer
values : 1, 10 (min, max)
I would just reassign the values which will preserve the metadata, and re-write the file:
af1_patch <-raster(a_files[6])
af1_area <-raster(a_files[1])
af1_patch[] <- af1_area[]
#writeRaster(af1_patch, a_files[1], ...)
I have two netCDF files with different extents and resolutions. I would like to create rasters from both files that are the same extent and resolution. I want the resolution from one file, and the extent from the other.
Here is the code I'm using:
require(raster);
#Get information
iceMaxNineK <- raster("~/Desktop/TRACE-21k_Data/NineK.ICEFRAC.max.avg.nc")
saltNineK <- brick("~/Desktop/TRACE-21k_Data/NineK.SALT.nc", lvar = 4)
#Making everything nice and uniform and useable
#==============================================
#set up an initial "sampling raster"
e <- extent(0, 360, -90, 90) #xmin,xmax,ymin,ymax
e <- raster(e,nrows=1,ncols=1,crs=saltNineK#crs)
res(e) <- res(saltNineK)
values(e) <- 0
#Resample ice
iceMaxNineK <- resample(iceMaxNineK, e, method="ngb")
plot(iceMaxNineK)
#Resample salt
saltNineK <- resample(saltNineK, e, method="ngb")
plot(saltNineK)
Resampling iceMaxNineK works, but resampling saltNineK results in a map that is jammed up into one corner of the defined area of extent, as shown in the pictures below.
First, iceMaxNineK:
Second, saltNineK:
Dimensions of iceMaxNineK before resampling:
class : RasterLayer
dimensions : 48, 96, 4608 (nrow, ncol, ncell)
resolution : 3.75, 3.708898 (x, y)
extent : -1.875, 358.125, -89.01354, 89.01354 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
data source : /Users/Hannah/Desktop/TRACE-21k_Data/NineK.ICEFRAC.max.avg.nc
names : Fraction.of.sfc.area.covered.by.sea.ice
z-value : -8.99945876078469
zvar : ICEFRAC
Dimensions of iceMaxNineK after resampling:
class : RasterLayer
dimensions : 180, 360, 64800 (nrow, ncol, ncell)
resolution : 1, 1 (x, y)
extent : 0, 360, -90, 90 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
data source : in memory
names : Fraction.of.sfc.area.covered.by.sea.ice
values : 0, 0.9997393 (min, max)
Dimensions of saltNineK before resampling:
class : RasterBrick
dimensions : 116, 100, 11600, 25 (nrow, ncol, ncell, nlayers)
resolution : 1, 1 (x, y)
extent : 0.5, 100.5, 0.5, 116.5 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
data source : /Users/Hannah/Desktop/TRACE-21k_Data/NineK.SALT.nc
names : X400, X1222.02453613281, X2108.88061523438, X3100.537109375, X4239.19677734375, X5577.873046875, X7187.42822265625, X9166.115234375, X11653.9140625, X14854.84765625, X19072.095703125, X24762.70703125, X32618.9296875, X43673.65625, X59384.83984375, ...
centimeters : 400, 475128.78125 (min, max)
varname : SALT
level : 1
Dimensions of saltNineK after resampling:
class : RasterBrick
dimensions : 180, 360, 64800, 25 (nrow, ncol, ncell, nlayers)
resolution : 1, 1 (x, y)
extent : 0, 360, -90, 90 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
data source : in memory
names : X400, X1222.02453613281, X2108.88061523438, X3100.537109375, X4239.19677734375, X5577.873046875, X7187.42822265625, X9166.115234375, X11653.9140625, X14854.84765625, X19072.095703125, X24762.70703125, X32618.9296875, X43673.65625, X59384.83984375, ...
min values : 6.842899, 6.850603, 6.853004, 6.853779, 6.853567, 23.148109, 23.148115, 23.148115, 23.148119, 23.148121, 23.148121, 23.148121, 23.148121, 23.148121, 23.148121, ...
max values : 39.60786, 39.60786, 39.60783, 39.60777, 39.60769, 39.60766, 39.60765, 39.60757, 39.60755, 39.60742, 39.60739, 39.60732, 39.60730, 39.60730, 39.60730, ...
Sample files can be accessed via the following link: https://www.dropbox.com/s/x8oqem317vmr7yq/DataForRResample.zip?dl=0
Thank you for your time.
I have now solved this question. The problem was the input file, which was at a T31_gx3v5 resolution (http://www.cgd.ucar.edu/ccr/TraCE/; Yeager et al., 2006; Otto-Bliesner et al., 2006). R doesn't pick up on this. The layers needed to be regridded to 1X1 degree using the ncl language before importing them into R. For more information on regridding in ncl, follow this link: https://www.ncl.ucar.edu/Document/Functions/Pop_remap/PopLatLon.shtml.