Share raster data - raster

Does anyone have any tips about how to share raster layers (or a part of it) in forums like this? I'd like to ask a question and give some reproducible data but I'm not sure what is the best way to do it.
Thanks a lot in advance!

stackoverflow, gis.stackexchange, r-sig-geo and the examples in the manuals of sp and the raster package and other packages are full of examples how to do that. Here are some:
library(raster)
# example files
f1 <- system.file("external/test.grd", package="raster")
r <- raster(f1)
f2 <- system.file("external/rlogo.grd", package="raster")
b <- brick(f2)
# create your own
x <- raster(nrow=18, ncol=36)
values(x) <- runif(ncell(x))
y <- raster(nrow=10, ncol=10, xmn=0, xmx=10, ymn=0, ymx=10, crs='+proj=utm +zone=2')
values(y) <- 1:ncell(y)

Answer given by Frede Aakmann Tøgersen.
For geographical data 'data(meuse.grid)' can be used as an example.

Related

How to extract rasters and points?

I am working on R and creating prediction maps. In my data, I have the location coordinates.
How to extract my rasters and points?
library(randomForest)
library(caret)
library(raster)
library(raster)
library(rgdal)
##-----load data
data <- read.csv("0.10.coordinates.csv",sep=";", header = TRUE)
raster(swi.tif)
rsp.1<-raster("rsp.tif")
twi.1<-raster("twi.tif")
swi.1<-raster("swi.tif")
###load csv of 0-10cm sand,silt and clay %'s and lat/long (x,y) (in E: drive RF folder)
xy<-read.csv("0.10.coordinates.csv")
plot(swi.1)
plot(twi.1)
plot(swi.1)
plot(rsp.1)
stack(swi.1,rsp.1,twi.1,xy)
topo.brick<-brick(rsp.1,swi.1,twi.1,xy)
brick(rsp.1,twi.1,swi.1,data)
df<-extract(data,rsp.1,twi.1,swi.1)`
Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘extract’ for signature ‘"data.frame", "RasterLayer"’
take a look at?raster::extract to see what inputs are required and in what order. In any case, you should create a reproducible example..
However, here an example with dummy data:
library(raster)
# with raster -------------------------------------------------------------
r <- s <- t <- raster()
r[] <- 1:ncell(r)
s[] <- sample(1:10,ncell(s),replace = T)
t[] <- runif(ncell(t))
stacked <- stack(r,s,t)
#points
xy <- cbind(-50, seq(-80, 80, by=20))
#extract
ex <- extract(stacked,xy, df=TRUE)
If the extraction takes too long, check out the terra::extract or even better a exactextractr::exact_extract.
See Elia's example, but from what I gather from your code you should be able to do
library(raster)
xy <- read.csv("0.10.coordinates.csv")
s <- stack("rsp.tif", "twi.tif", "swi.tif")
d <- extract(s, xy)`

How to do consecutive difference in raster stack data?

Assume that I have large RasterBrick, and I would like to do consecutive difference, which means layer2-layer1, layer3-layer2, layer4-layer3, ……..
I was thinking to use Raster package for this, but i am not able to do it. Could any one suggest me a working (guessing) code please ? I am not providing reproducible data thinking that the issue is clear.
Thanks in advance.
The following seems to work:
library(raster)
r1 = raster()
r2 = raster()
r3 = raster()
dim(r2)
r1[] = runif(180*360)
r2[] = runif(180*360)
r3[] = runif(180*360)
r = stack(r1,r2,r3)
dim(r)
rd = calc(r, fun = diff)
dim(rd)

Focal function: How do I get the value of the center pixel and use this value within the focal fun argument?

Example with a 3*3 neighborhood where the sum is multiplied with the center value "center".
library(raster)
r <- raster(ncol=10, nrow=10)
r[] <- 1:100
f<-function(x,center) {sum(x)*center}
r.f <- focal(r, w=matrix(1,3,3),fun=f}
Carl's approach will work. It might be more efficient to do:
library(raster)
r <- raster(ncol=10, nrow=10)
r[] <- 1:100
r.f <- focal(r, w=matrix(1,3,3)) * r
Interesting. Since the argument fun must accept multiple values, it may well be the case that you should use
f <-function(x) {
y = sum(x)/x[5]
return(y)
}
Because you're always feeding an x which is a 3x3 matrix, so the fifth element will be the center one.
No R on the machine I'm using to type this, so I can't verify :-(

Converting table with coordinates raster plot

I'm a total beginner and have what I believe is a rather simple problem, but I am kind of stuck...
I have a data table with three columns: x, y and height values. I've imported the csv file and extracted the values:
data <- read.csv("C:/Data/heights.csv")
mydata <- data[, c("x", "y", "height")]
I then need to put the height values into a grid with these coordinates, which I created as a raster:
grid <- raster(ncol=2001, nrow=2001, xmn=479975, xmx=500025, ymn=119975, ymx=140025)
I think you are very close. I'd suggest you reading the raster package material, the vignette and description.
You'll have to pay attention to your data and how it is organized. By row? Column? raster cells values will be populated by row.
Using something simmilar to the example provided in the help ?raster
library(raster)
vals <- 1:100
r1 <- raster(nrows=10, ncols=10, xmn=479975, xmx=500025, ymn=119975, ymx=140025)
r1[] <- vals
plot(r1)
But the procedure may be different approaching with a spatial object
library(sp)
x <- 1:10
y <- 1:10
df <- data.frame(expand.grid(x=x,y=y), v=1:100)
coordinates(df)=~x+y
gridded(df) = TRUE
r2 <- raster(df)
plot(r2)
I think this may be the best approach but it would be better to have an idea about your data and how it is organized.
You could try this:
library(raster)
x <- rasterFromXYZ(mydata)
extent(x) <- c(479975, 500025, 119975, 140025)

Function for resizing matrices in R

I was wondering if there was a function that scales down matrices in R statistical software exactly like with image resizing. The function imresize() in MATLAB is exactly what I'm looking for (I believe it takes the average of the surrounding points, but I am not sure of this), but I am wondering if there is an R equivalent for this function.
This question has been posted before on this forum, but with reference to MATLAB, not R:
Matlab "Scale Down" a Vector with Averages
The post starting with "Any reason why you can't use the imresize() function?" is exactly what I am looking for, but in R, not MATLAB.
Say I have a latitude-longitude grid of temperatures around the world, and let's say this is represented by a 64*128 matrix of temperatures. Now let's say I would like to have the same data contained in a new matrix, but I would like to rescale my grid to make it a 71*114 matrix of temperatures around the world. A function that would allow me to do so is what I'm looking for (again, the imresize() function, but in R, not MATLAB)
Thank you.
Steve
One way to do this is by using the function resample(), from the raster package.
I'll first show how you could use it to rescale your grid, and then give an easier-to-inspect example of its application to smaller raster objects
Use resample() to resize matrices
library(raster)
m <- matrix(seq_len(68*128), nrow=68, ncol=128, byrow=TRUE)
## Convert matrix to a raster with geographical coordinates
r <- raster(m)
extent(r) <- extent(c(-180, 180, -90, 90))
## Create a raster with the desired dimensions, and resample into it
s <- raster(nrow=71, ncol=114)
s <- resample(r,s)
## Convert resampled raster back to a matrix
m2 <- as.matrix(s)
Visually confirm that resample() does what you'd like:
library(raster)
## Original data (4x4)
rr <- raster(ncol=4, nrow=4)
rr[] <- 1:16
## Resize to 5x5
ss <- raster(ncol=5, nrow=5)
ss <- resample(rr, ss)
## Resize to 3x3
tt <- raster(ncol=3, nrow=3)
tt <- resample(rr, tt)
## Plot for comparison
par(mfcol=c(2,2))
plot(rr, main="original data")
plot(ss, main="resampled to 5-by-5")
plot(tt, main="resampled to 3-by-3")
The answer posted by Josh O'Brien is OK and it helped me (for starting point), but this approach was too slow since I had huge list of data. The method below is good alternative. It uses fields and works much faster.
Functions
rescale <- function(x, newrange=range(x)){
xrange <- range(x)
mfac <- (newrange[2]-newrange[1])/(xrange[2]-xrange[1])
newrange[1]+(x-xrange[1])*mfac
}
ResizeMat <- function(mat, ndim=dim(mat)){
if(!require(fields)) stop("`fields` required.")
# input object
odim <- dim(mat)
obj <- list(x= 1:odim[1], y=1:odim[2], z= mat)
# output object
ans <- matrix(NA, nrow=ndim[1], ncol=ndim[2])
ndim <- dim(ans)
# rescaling
ncord <- as.matrix(expand.grid(seq_len(ndim[1]), seq_len(ndim[2])))
loc <- ncord
loc[,1] = rescale(ncord[,1], c(1,odim[1]))
loc[,2] = rescale(ncord[,2], c(1,odim[2]))
# interpolation
ans[ncord] <- interp.surface(obj, loc)
ans
}
Lets look how it works
## Original data (4x4)
rr <- matrix(1:16, ncol=4, nrow=4)
ss <- ResizeMat(rr, c(5,5))
tt <- ResizeMat(rr, c(3,3))
## Plot for comparison
par(mfcol=c(2,2), mar=c(1,1,2,1))
image(rr, main="original data", axes=FALSE)
image(ss, main="resampled to 5-by-5", axes=FALSE)
image(tt, main="resampled to 3-by-3", axes=FALSE)

Resources