I have a categorical raster layer that I need to one-hot encode, as I'm using neural networks to run a species distribution model (for a class) and it only works on continuous predictors. I've already run the model with the one-hot encoded data itself, but in order to predict onto a map, the raster itself needs to be one-Hot encoded in the same way.
In the RStoolbox package, oneHotEncode() should do what I need it to do, but I can't get it to work
nn.raster<-oneHotEncode(newraster$NLCD_2016_Land_Cover_oreg, classes=values, background = 0, foreground = 1, na.rm = FALSE)
Error message:
Error in .calcTest(x[1:5], fun, na.rm, forcefun, forceapply) :
cannot use this function. Perhaps add '...' or 'na.rm' to the function arguments?
Has anybody used this function and can help me troubleshoot? I think the problem is coming from the class's argument. My categories are numerical (from the national land cover raster), which is why they show up as "values" in the raster info. Do I need to do something to reclassify them? I think I'm naming them wrong but I'm not sure how.
After giving a quick look at RStoolbox::oneHotEncode, I am under the impression that it does what raster::layerize also does.
library(raster)
r <- raster(nrow=20, ncol=20)
values(r) <- c(rep(NA, 50), rep(1:5, 70))
r
#class : RasterLayer
#dimensions : 20, 20, 400 (nrow, ncol, ncell)
#resolution : 18, 9 (x, y)
#extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
#crs : +proj=longlat +datum=WGS84 +no_defs
#source : memory
#names : layer
#values : 1, 5 (min, max)
b <- layerize(r)
b
#class : RasterBrick
#dimensions : 20, 20, 400, 5 (nrow, ncol, ncell, nlayers)
#resolution : 18, 9 (x, y)
#extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
#crs : +proj=longlat +datum=WGS84 +no_defs
#source : memory
#names : X1, X2, X3, X4, X5
#min values : 0, 0, 0, 0, 0
#max values : 1, 1, 1, 1, 1
Which is equivalent to terra::separate
library(terra)
r <- rast(nrow=5, ncol=5)
values(r) <- rep(c(1:4, NA), each=5)
b <- separate(r)
Related
I am trying to calculate the spatial correlation between two rasters. I have two large rasters with the same extent, resolution, etc
class : RasterLayer
dimensions : 45598, 53241, 2427683118 (nrow, ncol, ncell)
resolution : 30, 30 (x, y)
extent : 273366.8, 1870597, 367780.7, 1735721 (xmin, xmax, ymin, ymax)```
These layers have massive NAs cells
I tried to use terra::focalCor with the stack of those layers.
corr=focalCor(layerstack, w=9, cor)
But I have this issue
Error in v[[j - 1]] <- t(sapply(1:nrow(Y), function(i, ...) fun(X[i, ], :
more elements supplied than there are to replace
Any ideas or suggestions?
Cheers
It would have been easier to provide a specific answer with actual data provided to be able to reproduce your issue, but in this case it seems like you imported your gridded data using raster::raster() creating a RasterLayer object, but according to ?focalCor, x has clearly to be a SpatRaster with at least two layers.
So, try terra::rast(c("grid_1.tif", "grid_2.tif")) |> terra::focalCor(w = 9, cor) instead.
Edit:
Thanks for your reprex. I dared to reduce dimensions and modify the extent a little bit in order to reduce processing time:
library(terra)
r <- rast(ncols = 100, nrows = 100,
xmin = 0, xmax = 25, ymin = 0, ymax = 25,
crs = "epsg:4326")
r1 <- init(r, fun = runif)
r2 <- init(r, fun = runif)
r_stack <- c(r1, r2)
r_stack_cor_5 <- focalCor(r_stack, w = 5, cor)
r_stack_cor_5
#> class : SpatRaster
#> dimensions : 100, 100, 1 (nrow, ncol, nlyr)
#> resolution : 0.25, 0.25 (x, y)
#> extent : 0, 25, 0, 25 (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 (EPSG:4326)
#> source : memory
#> name : lyr1
#> min value : -0.6476946
#> max value : 0.6948594
r_stack_cor_25 <- focalCor(r_stack, w = 25, cor)
r_stack_cor_25
#> class : SpatRaster
#> dimensions : 100, 100, 1 (nrow, ncol, nlyr)
#> resolution : 0.25, 0.25 (x, y)
#> extent : 0, 25, 0, 25 (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 (EPSG:4326)
#> source : memory
#> name : lyr1
#> min value : -0.1020998
#> max value : 0.1045798
I used fun = cor instead of function(x, y) cor(x, y) but the result is the same according to all.equal(). However, your example seems to work - and I'm failing to recognize the issue at the moment.
I have an image that must be processed with the package magick. So the output belongs to class magick-image. I need to transform it to a class rasterBrick for further processing.
How can I transform an object magick-image to rasterBrick? I need to avoid saving and loading an intermediate temp file.
library(magick)
library(raster)
# load sample image
i <- image_read("https://i.picsum.photos/id/10/2500/1667.jpg?hmac=J04WWC_ebchx3WwzbM-Z4_KC_LeLBWr5LZMaAkWkF68")
# does not work
r <- raster::raster(i)
# workaround that I must avoid
image_write(i,"temp_image.jpg")
t <- brick("temp_image.jpg")
t
You can do this:
library(terra)
r <- as.raster(i) |> as.matrix() |> rast()
r
#class : SpatRaster
#dimensions : 1667, 2500, 3 (nrow, ncol, nlyr)
#resolution : 1, 1 (x, y)
#extent : 0, 2500, 0, 1667 (xmin, xmax, ymin, ymax)
#coord. ref. :
#source : memory
#colors RGB : 1, 2, 3
#names : red, green, blue
#min values : 0, 8, 0
#max values : 252, 250, 248
plot(r)
You may want to stick with terra, but if you want to go back to a RasterBrick, you can add
library(raster)
b <- brick(r)
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 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.
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.