Related
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 want to create subsets of raster stacks and write them as new stacks when the difference between the previous layer and the next layer is all NA. I.e., starting from layer 1, I want to create a subset of raster stacks until there are no-overlapping pixels between the previous and next layers (i.e., the difference between the two layers is all NA) So I want is; starting from layer 1, retain all the layers that have at least 1 common pixel between the previous and next layer, write them as a 1 stack, and move to the next. Below are a sample data and unsuccessful for-loop. In this example, I want to retain layers 1:8, name and write them and start again from layer 9 and so on.
r <- raster(ncol=5, nrow=5)
set.seed(0)
#create raster layers with some values
s <- stack(lapply(1:8, function(i) setValues(r, runif(ncell(r)))))
s1<-extend(s,c(-500,100,-400,100))
#to recreate the condition I am looking for, create 2 layers with `NA` vlaues
s2 <- stack(lapply(1:2, function(i) setValues(r, runif(ncell(r)))))
s1e<-extend(s2,c(-500,100,-400,100))
s1e[]<-NA
#Stack the layers
r_stk<-stack(s1,s1e)
plot(r_stk)
#here is the sample code showing what i am expecting here but could not get
required_rst_lst<-list() # sample list of raster layers with overlapping pixels I am hoping to create
for ( i in 1: nlayers(r_stk))
# i<-1
lr1<-subset(r_stk,i)
lr1
lr2<-subset(r_stk,i+1)
lr2
diff_lr<-lr1-lr2
plot(diff_lr)
if ((sum(!is.na(getValues(diff_lr)))) ==0)) #??
required_rst_lst[[i]] #?? I want layers 1: 8 in this list
#because the difference in these layers in not NA
Something like this may work for you.
Your example data
library(raster)
r <- raster(ncol=5, nrow=5)
set.seed(0)
s <- stack(lapply(1:8, function(i) setValues(r, runif(ncell(r)))))
s1 <- extend(s,c(-500,100,-400,100))
s2 <- stack(lapply(1:2, function(i) setValues(r, runif(ncell(r)))))
s1e <- extend(s2,c(-500,100,-400,100))
values(s1e) <- NA
r_stk <- stack(s1,s1e)
Solution:
out <- lst <- list()
nc <- ncell(r_stk)
for (i in 1:nlayers(r_stk)) {
if (i==1) {
j <- 1
s <- r_stk[[i]]
} else {
s <- s + r_stk[[i]]
}
if (freq(s, value=NA) == nc) {
ii <- max(j, i-1)
out <- c(out, r_stk[[j:ii]])
s <- r_stk[[i]]
j <- i
}
}
out <- c(out, r_stk[[j:i]])
out
#[[1]]
#class : RasterStack
#dimensions : 14, 9, 126, 8 (nrow, ncol, ncell, nlayers)
#resolution : 72, 36 (x, y)
#extent : -468, 180, -414, 90 (xmin, xmax, ymin, ymax)
#crs : +proj=longlat +datum=WGS84 +no_defs
#names : layer.1.1, layer.2.1, layer.3, layer.4, layer.5, layer.6, layer.7, layer.8
#min values : 0.06178627, 0.01339033, 0.07067905, 0.05893438, 0.01307758, 0.03554058, 0.06380848, 0.10087313
#max values : 0.9919061, 0.8696908, 0.9128759, 0.9606180, 0.9926841, 0.9850952, 0.8950941, 0.9437248
#
#[[2]]
#class : RasterLayer
#dimensions : 14, 9, 126 (nrow, ncol, ncell)
#resolution : 72, 36 (x, y)
#extent : -468, 180, -414, 90 (xmin, xmax, ymin, ymax)
#crs : +proj=longlat +datum=WGS84 +no_defs
#source : memory
#names : layer.1.2
#values : NA, NA (min, max)
#
#[[3]]
#class : RasterLayer
#dimensions : 14, 9, 126 (nrow, ncol, ncell)
#resolution : 72, 36 (x, y)
#extent : -468, 180, -414, 90 (xmin, xmax, ymin, ymax)
#crs : +proj=longlat +datum=WGS84 +no_defs
#source : memory
#names : layer.2.2
#values : NA, NA (min, max)
I want to extract a variable called NVEL from the netCDF file which has five dimensions (i, j, tile, k, time)
where i is longitude, j is latitude, k is the level of depths
I want to extract NVEL(i, j, tile=3, k=1st level, time)
the input file can be downloaded from here https://drive.google.com/file/d/12NQp_uLr_IZLLU6Fzr555gKGGJlrRE4H/view?usp=sharing
NVEL<- brick("NVEL_1992_01.nc", varname= "NVEL", lvar=1, nl=1)
NVEL <- NVEL[[which(getZ(NVEL) == 3)]]
This does not work.
How to deal with a variable of 5 dimensions?
I see that this returns 50 (k) * 13 (tiles) * 1 (time) = 650 layers
library(terra)
f <- "NVEL_1992_01.nc"
x <- rast(f)
x
#class : SpatRaster
#dimensions : 90, 90, 650 (nrow, ncol, nlyr)
#resolution : 1, 1 (x, y)
#extent : -0.5, 89.5, -0.5, 89.5 (xmin, xmax, ymin, ymax)
#coord. ref. : +proj=longlat +datum=WGS84 +no_defs
#data source : NVEL_1992_01.nc
#names : NVE_1, NVE_2, NVE_3, NVE_4, NVE_5, NVE_6, ...
The order is k-wise (and tile-wise within tiles). See (the rather lengthy) output from
terra::describe(f)
You can extract that information like this:
d <- describe(f, print=FALSE)
d <- unlist(strsplit(d, "\n"))
i <- grep("NETCDF_DIM_k=", d)
j <- grep("NETCDF_DIM_tile=", d)
k <- sapply(strsplit(d[i], "="), function(x) x[2])
tile <- sapply(strsplit(d[j], "="), function(x) x[2])
kt <- paste0("k", k, "_tile", tile)
names(x) <- kt
x
#class : SpatRaster
#dimensions : 90, 90, 650 (nrow, ncol, nlyr)
#resolution : 1, 1 (x, y)
#extent : -0.5, 89.5, -0.5, 89.5 (xmin, xmax, ymin, ymax)
#coord. ref. : +proj=longlat +datum=WGS84 +no_defs
#data source : NVEL_1992_01.nc
#names : k0_tile0, k0_tile1, k0_tile2, k0_tile3, k0_tile4, k0_tile5, ...
This should happen automatigically in a future version. You can continue with terra (very similar to raster) or take the data back to a RasterBrick by doing
b <- brick(x*1)
(multiplying to get the values out of the file)
I'm looking for a tip on how to recode time/date dimension of a netcdf file/raster brick. I extracted a monthly temperature data and the date dimension is not in the standard date format. For example, 1850.04166666667, 1850.125, means January and February 1850 respectively in the data and R couldn't understand them. Here's the data structure
> eco.sst
class : RasterBrick
dimensions : 180, 360, 64800, 2030 (nrow, ncol, ncell, nlayers)
resolution : 1, 1 (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 : C:\Users\Admin\AppData\Local\Temp\Rtmp6vFWNG\raster\r_tmp_2019-04-18_183528_11516_79080.grd
names : X1850.04166666667, X1850.125, X1850.20833333333, X1850.29166666667, X1850.375, X1850.45833333333, X1850.54166666667, X1850.625, X1850.70833333333, X1850.79166666667, X1850.875, X1850.95833333333, X1851.04166666667, X1851.125, X1851.20833333333, ...
min values : -0.668686926, -0.273689777, -1.902773499, -3.406341553, -3.626811743, -2.131400585, -1.569969416, -1.630665064, -2.418994188, -1.971702099, -0.822018623, -3.423746109, -1.303600550, -0.786648691, -1.452626705, ...
max values : 3.926926e+00, 1.550823e+00, 1.151636e+00, 6.622851e-01, 9.673859e-01, 7.178870e-01, 9.010030e-01, 4.363060e-01, 5.231520e-01, 3.346115e-01, 2.156055e-01, 6.418970e-01, 2.259051e+00, 3.802529e+00, 2.077996e+00, ...
time : 1850.04166666667, 2019.125 (min, max)
I wrote a function to replace the decimal points;
fun.repl = function (x, na.rm = TRUE) str_replace(x, ".04166666667", "-1")
such that 1850.04166666667, which means January 1850 becomes 1850-1;
which I then applied to the raster in the form:
stackApply(eco.sst, "time", fun.repl)
eco.sst is the raster brick while "time" is referencing the time dimension. But the function did not work. I suspect that I don't understand the data structure well enough to successfully apply the function. I'm new to this and also finding out that this is a rare problem with netcdf.
I expect 1850.04166666667, 1850.125, 1850.20833333333, 1850.29166666667...which means January to April 1850 to become standard dates in the form.... 1850-1, 1850-2, 1850-3, 1850-4 etc
Here is another way to get the dates
todate <- function(x) {
year <- trunc(x)
month <- round(12 * ((x - year) + 1/24))
as.Date(paste0(year, "-", month, "-15"))
}
dts <- c(1850.04166666667, 1850.125)
d <- todate(dts)
d
#[1] "1850-01-15" "1850-02-15"
Note that I use the 15th day for each month in order to get a valid date --- but that seems to be what is intended.
Now you probably want to use setZ, see the example below. (stackApply makes no sense here and the arguments you use are not valid either)
library(raster)
r <- raster(ncol=10, nrow=10)
s <- stack(lapply(1:2, function(x) setValues(r, runif(ncell(r)))))
s <- setZ(s, d)
s
#class : RasterStack
#dimensions : 10, 10, 100, 2 (nrow, ncol, ncell, nlayers)
#resolution : 36, 18 (x, y)
#extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
#crs : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
#names : layer.1, layer.2
#min values : 0.01477963, 0.01178438
#max values : 0.9980334, 0.9939610
#time : 1850-01-15, 1850-02-15
When I try to run band math the result is always an image of a color and the values min and max very different from the one predicted.
I did not find any question here that showed this problem.
I worked out this way
r.stack <- stack("path to raster file"))
I use resampling instead of crop to cut out the white edges that were in the original images
prj <- "+proj=utm +zone=23 +south +datum=WGS84 +units=m"
r <- raster(res=11.47, ext=extent(c(301496, 323919, 9888968, 9913982)), crs=prj, vals=NA
r.stack <- resample(r.stack, r)
After that the images have this configuration:
> class : RasterBrick
> dimensions : 2181, 1955, 4263855, 4 (nrow, ncol, ncell, nlayers)
> resolution : 11.47, 11.47 (x, y)
> extent : 301496, 323919.8, 9888966, 9913982 (xmin, xmax, ymin, ymax)
>coord. ref. : +proj=utm +zone=23 +south +datum=WGS84 +units=m +ellps=WGS84 +towgs84=0,0,0
>data source : in memory
>names : l.1, l.2, l.3, l.4
>min values : -36.12217, -45.12768, -46.30455, -35.26328
>max values : 10.567671, 4.050200, 3.878345, 11.613799
and than use the function below for calc
f <- function(x){
(x[[2]])/(x[[1]])
}
s <- r.stack[[c(1,2)]]
r2 <- calc(s, f)
and I also run overlay whit the fun
f <- function(x,y){
y/x
}
r2 <- overlay(r.stack[[1]], r.stack[[2]], fun= f)
Any of the methods result in a image of one value
Am I missing some steps?
Here is your code with some example data (without that it is hard to answer questions). I have simplified one function, a bit, but the results are the same.
library(raster)
b <- brick(system.file("external/rlogo.grd", package="raster"))
b <- b/10 + 1
f <- function(x){ x[2]/ x[1] }
s <- b[[c(1,2)]]
r1 <- calc(s, f)
f <- function(x,y){ y / x }
r2 <- overlay(b[[1]], b[[2]], fun= f)
Or simply
r3 <- b[[2]] / b[[1]]
r3
#class : RasterLayer
#dimensions : 77, 101, 7777 (nrow, ncol, ncell)
#resolution : 1, 1 (x, y)
#extent : 0, 101, 0, 77 (xmin, xmax, ymin, ymax)
#coord. ref. : +proj=merc +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
#data source : in memory
#names : layer
#values : 0.7692308, 1.7 (min, max)
r1 and r2 are the same.
The reason that you get a "single color" is because most values are near 1, but there are a few big outliers; probably because of a division by a number between -1 and 1? This might illustrate it:
q <- quantile(r3, c(0.1, 0.9))
d <- clamp(r3, q[1], q[2])
plot(d)
And look at the extremes
i <- which.max(r3)
b[i][,2:1]