I have a NetCDF file of salinity in Indonesia water with 4 dimensions (lon, lat, depth and time). How to create create weekly composite from my data
download data here: https://onedrive.live.com/redir?resid=6FFDD661570C7D0A%21177
output map here: https://onedrive.live.com/redir?resid=6FFDD661570C7D0A%21176
I would like to convert the raster into vector and the use apply to get the mean, but I have problem to plot the vector data using rasterVis
With your example, nor really complicated:
# load needed librairies
library(rasterVis)
# open the data
salinity <- brick("data.nc", varname = "salinity")
salinity
# class : RasterBrick
# dimensions : 61, 61, 3721, 5 (nrow, ncol, ncell, nlayers)
# resolution : 0.08333333, 0.08333333 (x, y)
# extent : 104.9583, 110.0417, -5.041667, 0.04166667 (xmin, xmax, ymin, ymax)
# coord. ref. : +proj=longlat +datum=WGS84
# data source : data.nc
# names : X252331200, X252417600, X252504000, X252590400, X252676800
# z-value : 252331200, 252417600, 252504000, 252590400, 252676800
# varname : salinity
# level : 1
# Calculate the mean
m.salinity <- mean(salinity)
m.salinity
# class : RasterLayer
# dimensions : 61, 61, 3721 (nrow, ncol, ncell)
# resolution : 0.08333333, 0.08333333 (x, y)
# extent : 104.9583, 110.0417, -5.041667, 0.04166667 (xmin, xmax, ymin, ymax)
# coord. ref. : +proj=longlat +datum=WGS84
# data source : in memory
# names : layer
# values : 18.85652, 31.84299 (min, max)
Related
Simply trying to use a vector (.shp) to mask a SpatRaster using terra::mask; get the following error
>Error: \[mask\] cannot create dataset
LCC84 <- rast("C:/Users_forest_VLCE2_1984.tif")
vec <- vect("C:/Users/Land_Management_Units.shp")
vec_proj <- project(vec, LCC84)
LCC84_masked <- terra::mask(LCC84, vec_proj)
Error: [mask] cannot create dataset
vec
#class : SpatVector
#geometry : polygons
#dimensions : 1, 8 (geometries, attributes)
#extent : -117.3165, -115.1691, 50.70613, 52.27127 (xmin, xmax, ymin, ymax)
#coord. ref. : lon/lat NAD83 (EPSG:4269)
LCC84
#class : SpatRaster
#dimensions : 128340, 193936, 1 (nrow, ncol, nlyr)
#resolution : 30, 30 (x, y)
#extent : -2660911, 3157169, -851351.9, 2998848 (xmin, xmax, ymin, ymax)
#coord. ref.: Lambert_Conformal_Conic_2SP
#source : CA_forest_VLCE2_1984.tif
#name : CA_forest_VLCE2_1984
crs(LCC84, proj=TRUE)
[1] "+proj=lcc +lat_0=49 +lon_0=-95 +lat_1=49 +lat_2=77 +x_0=0 +y_0=0 +datum=NAD83 +units=m +no_defs"
You can use the following code
library(terra)
library(sf)
#Read the data
LCC84 <- rast("C:/Users_forest_VLCE2_1984.tif")
vec <- st_read("C:/Users/Land_Management_Units.shp")
#Convert the crs of shapefile
vec_proj <- sf::st_transform(vec, crs(LCC84))
#Masking the raster using the shapefile
LCC84_masked <- terra::mask(LCC84, vec_proj)
It works for me with the data you provided
library(terra)
#terra 1.6.51
v <- vect("Extent_BNP_Extact.shp")
r <- rast("CA_forest_VLCE2_1984.tif")
pv <- project(v, r)
z <- crop(r, pv, mask=T)
r
#class : SpatRaster
#dimensions : 128340, 193936, 1 (nrow, ncol, nlyr)
#resolution : 30, 30 (x, y)
#extent : -2660911, 3157169, -851351.9, 2998848 (xmin, xmax, ymin, ymax)
#coord. ref. : Lambert_Conformal_Conic_2SP
#source : CA_forest_VLCE2_1984.tif
#name : CA_forest_VLCE2_1984
v
# class : SpatVector
# geometry : polygons
# dimensions : 1, 2 (geometries, attributes)
# extent : 474065.5, 635666.6, 5613645, 5798288 (xmin, xmax, ymin, ymax)
# source : Extent_BNP_Extact.shp
# coord. ref. : NAD83 / UTM zone 11N (EPSG:26911)
# names : Shape_Leng Shape_Area
# type : <num> <num>
# values : 6.744e+05 2.828e+10
plot(z)
First cropping seems logical here because the entire dataset has ~25 billion cells. I also tried
mask(r, pv)
It took a while to run, but it worked. If it does not for you, my guess would be that you may not have sufficient disk-space in your temp folder. See terraOptions() for the location of the temp folder.
Also, you do the equivalent of
pv <- project(v, "EPSG:4269")
But that makes no sense, as your raster data do not have the EPSG:4269 coordinate reference system (lon/lat NAD83).
Sorry for the very stupid question, but I'm really stuck here... I need to create a Digital Elevation Model for my study area. For this, I downloaded an SRTM (1 arc-seg resolution, freely available from the net) image, which comprises a region wider than my area of interest. The original raster has these characteristics:
class : RasterLayer
dimensions : 3601, 3601, 12967201 (nrow, ncol, ncell)
resolution : 0.0002777778, 0.0002777778 (x, y)
extent : -45.00014, -43.99986, -22.00014, -20.99986 (xmin, xmax, ymin, ymax)
crs : +proj=longlat +datum=WGS84 +no_defs
source : s22_w045_1arc_v3.tif
names : s22_w045_1arc_v3
values : -32768, 32767 (min, max)
I need to (1) increase the resolution (initially of 30.75662 * 28.68392 m) to 1 * 1 m (that is, I really do not care about the exactitude of the elevations) and (2) crop a squared area of 2000 * 2000 m centered at a given coordinate. So, the first step I'm following is to re-project to UTM:
projection(r) <- "+proj=utm +zone=23 +datum=WGS84"
But the resolution units do not change after that:
class : RasterLayer
dimensions : 3601, 3601, 12967201 (nrow, ncol, ncell)
resolution : 0.0002777778, 0.0002777778 (x, y)
extent : -45.00014, -43.99986, -22.00014, -20.99986 (xmin, xmax, ymin, ymax)
crs : +proj=utm +zone=23 +datum=WGS84 +units=m +no_defs
source : s22_w045_1arc_v3.tif
names : s22_w045_1arc_v3
values : -32768, 32767 (min, max)
If I try to set the resolutions in meters manually, then generates an empty raster. Can anybody be so kind as to throw some light on me here?
You are changing (i.e. overwriting) the CRS, not projecting the raster. Usually, it is recommended to create a template raster with the CRS and the resolution you need and reproject the raster using this template.
See here an example, I am switching to terra for the analysis since it is a newer and faster package, but I would show also how to convert it back to raster format:
library(raster)
#> Loading required package: sp
# Faking your data
r <- raster(
nrows = 3601, ncols = 3601,
ext = extent(c(-45.00014, -43.99986, -22.00014, -20.99986))
)
values(r) <- seq(-32768, 32767, length.out = ncell(r))
r
#> class : RasterLayer
#> dimensions : 3601, 3601, 12967201 (nrow, ncol, ncell)
#> resolution : 0.0002777784, 0.0002777784 (x, y)
#> extent : -45.00014, -43.99986, -22.00014, -20.99986 (xmin, xmax, ymin, ymax)
#> crs : +proj=longlat +datum=WGS84 +no_defs
#> source : memory
#> names : layer
#> values : -32768, 32767 (min, max)
plot(r)
# End of faking data
# Change to terra, much faster
library(terra)
#> terra 1.5.21
r_terra <- terra::rast(r)
template <- terra::project(r_terra, "+proj=utm +zone=23 +datum=WGS84")
# Change to the desired res
res(template) <- c(2000, 2000)
# Reproject
r_terra_reproj <- terra::project(r_terra, template)
r_terra_reproj
#> class : SpatRaster
#> dimensions : 56, 52, 1 (nrow, ncol, nlyr)
#> resolution : 2000, 2000 (x, y)
#> extent : 499985.4, 603985.4, -2433195, -2321195 (xmin, xmax, ymin, ymax)
#> coord. ref. : +proj=utm +zone=23 +datum=WGS84 +units=m +no_defs
#> source : memory
#> name : layer
#> min value : -32371.95
#> max value : 32182.81
terra::plot(r_terra_reproj)
# Back to RasterLayer
r_reproj <- raster(r_terra_reproj)
r_reproj
#> class : RasterLayer
#> dimensions : 56, 52, 2912 (nrow, ncol, ncell)
#> resolution : 2000, 2000 (x, y)
#> extent : 499985.4, 603985.4, -2433195, -2321195 (xmin, xmax, ymin, ymax)
#> crs : +proj=utm +zone=23 +datum=WGS84 +units=m +no_defs
#> source : memory
#> names : layer
#> values : -32371.95, 32182.81 (min, max)
Created on 2022-06-10 by the reprex package (v2.0.1)
I have a netcdf file that contains 79 variables, and for each variable there are 365 bands (one for each day of the year). I want to read all bands of one variable (i.e., a raster with 365 ayers). With the 'raster' package this would work as follows:
dailyvalues <- brick('GLOBAL_2010_day.nc', varname ='WDEP_PREC')
Result is a RasterBrick with 365 layers:
> dailyvalues
class : RasterBrick
dimensions : 180, 360, 64800, 365 (nrow, ncol, ncell, nlayers)
resolution : 1, 1 (x, y)
extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
crs : +proj=longlat +datum=WGS84 +no_defs
source : GLOBAL_2010_day.nc
names : X2010.01.01, X2010.01.02, X2010.01.03, X2010.01.04, X2010.01.05, X2010.01.06, X2010.01.07, X2010.01.08, X2010.01.09, X2010.01.10, X2010.01.11, X2010.01.12, X2010.01.13, X2010.01.14, X2010.01.15, ...
Date : 2010-01-01, 2010-12-31 (min, max)
varname : WDEP_PREC
But I haven't suceeded to do this with the 'terra' package. I tried
dailyvalues <- rast('GLOBAL_2010_day.nc')
> dailyvalues
class : SpatRaster
dimensions : 180, 360, 28835 (nrow, ncol, nlyr)
resolution : 1, 1 (x, y)
extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +no_defs
sources : GLOBAL_2010_day.nc:WDEP_PREC (365 layers)
GLOBAL_2010_day.nc:WDEP_SOX (365 layers)
GLOBAL_2010_day.nc:WDEP_OXN (365 layers)
... and 76 more source(s)
varnames : WDEP_PREC (WDEP_PREC)
WDEP_SOX (WDEP_SOX)
WDEP_OXN (WDEP_OXN)
...
names : WDEP_PREC_1, WDEP_PREC_2, WDEP_PREC_3, WDEP_PREC_4, WDEP_PREC_5, WDEP_PREC_6, ...
unit : mm, mm, mm, mm, mm, mm, ...
time : 2010-01-01 18:00:00 to 2010-12-31 12:00:00
The resulting SpatRaster has 79 'sources', but what is the syntax to use if I want to extract one 'source'? Adding varname = 'WDEP_PREC' in the rast function doesn't work. I tried dailyvalues$... but that calls single layers only (as listed under 'names').
The argument to use is called subds in terra.
dailyvalues = rast("GLOBAL_2010_day.nc", subds="WDEP_PREC")
You should be able to do (as #dww says)
dailyvalues = rast("GLOBAL_2010_day.nc", subds="WDEP_PREC")
Or you can make a SpatRasterDataset
x = sds("GLOBAL_2010_day.nc")
And then extract the sub-dataset you want with
r <- x["WDEP_PREC"]
or
r <- x[1]
Furthermore, you can do
r <- rast('NETCDF:"GLOBAL_2010_day.nc:WDEP_PREC":WDEP_PREC')
(for the above to work you may need to add the path to the filename, or set your working directory to where it is)
I am trying to align two raster grids in R. Once aligned I would like to be able to add them together.
I have tried to check whether making a stack would work:
grid_snap <- stack(GLC2000_sdw, afriPop_sdw)
And I get the following error:
Error in compareRaster(x) : different extent
The raster grids have the following properties:
show(habi_sdw)
# class : RasterLayer
# dimensions : 9187, 9717, 89270079 (nrow, ncol, ncell)
# resolution : 0.00892857, 0.00892857 (x, y)
# extent : -28.83706, 57.92186, -36.02464, 46.00214 (xmin, xmax, ymin, ymax)
# coord. ref. : +proj=longlat +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +no_defs
# data source : C:\Users\di39\AppData\Local\Temp\R_raster_di39\raster_tmp_2015-08-12_172902_12860_17067.grd
# names : layer
# values : 0, 333707.6 (min, max)
show(Pop_sdw)
# class : RasterLayer
# dimensions : 10143, 8858, 89846694 (nrow, ncol, ncell)
# resolution : 0.008333333, 0.008333333 (x, y)
# extent : -17.53524, 56.28143, -46.97893, 37.54607 (xmin, xmax, ymin, ymax)
# coord. ref. : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0
# data source : C:\Users\di39\AppData\Local\Temp\R_raster_di39\raster_tmp_2015-08-12_170421_12860_12760.grd
# names : pop2010ppp
# values : 0, 128925.9 (min, max)
Using alignExtent() in the raster package seems not to be the correct approach.
Do I need to resample because the resolutions are slightly different?
(0.00892857 x 0.00892857) vs (0.008333333 vs 0.008333333)
First use resample(GLC2000_sdw, afriPop_sdw, method="ngb") and then crop (GLC2000_sdw, afriPop_sdw) to make sure they have the same extent.
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.