Count points from shapefile within raster cells - r

Is it in some way possible to count the number of points from a shapefile within each cell of a rasterfile using R?
The Idea is to retrieve a dataframe containing one row for each cell in the raster and a column with the number of points within that cell while keeping the original value from the raster cell.

library(raster)
# example raster and points data
r <- raster(ncols=10, nrows=5)
n <- 100
x <- runif(n) * 360 - 180
y <- runif(n) * 180 - 90
xy <- cbind(x, y)
rp <- rasterize(xy, r, fun=function(x,...)length(x))
as.data.frame(rp)

This answers the question in the title "how to count the number of points from a shapefile within each cell"
library(rgdal) # this package to read and manipulate shapefiles
library(raster) # this package for rasters
shp <- readOGR("my_shape_file.shp") # read in your points from the shape file
ras <- raster("my_raster_file") # read in your raster
shp <- spTransform(shp, projection(ras)) # make sure that the two spatial objects share the same coordinate system
cells <- cellFromXY(ras,shp) # find which cells the points are in
table(cells) # and make a table of number of occurences in each cell

Related

Manipulating raster values - increase its values by a randomly selected ratio from a range in R

I am working with a very large raster. I want to increase values in each pixel randomly by 0.3-0.5 of its original value. What kind of loop should I apply to achieve it elegantly?
Example raster built below. My raster is a .tif, and I would prefer not convert it to matrix first, unless it is the best solution?
library(raster)
## Create a matrix with random data & use image()
xy <- matrix(rnorm(400),20,20)
image(xy)
# Turn the matrix into a raster
rast <- raster(xy)
# Give it lat/lon coords for 36-37°E, 3-2°S
extent(rast) <- c(36,37,-3,-2)
# ... and assign a projection
projection(rast) <- CRS("+proj=longlat +datum=WGS84")
plot(rast)
No loops are necessary. You can access the underlying pixel data directly and simply add a set of random numbers to it:
rast2 <- rast # a copy of the existing raster
random_nums <- runif(length(rast2), min = 0.3, max = 0.5) # a set of random numbers the size of the image
rast2#data#values <- rast2#data#values * random_nums # multiply the pixel data by the random values

calculating road density raster from road shapefile

I'm looking to turn a shapefile with roads (which includes a column of length per road) in the Eastern half of the USA into a raster of 1x1km of road density, using R.
I can't find a straightforward way in Arcmap (Line density works with a radius from the cell center instead of just the cell).
Here is a solution that creates polygons from the raster cells (adapted from my answer here). You may need to to this for subsets of your dataset and then combine.
Example data
library(terra)
v <- vect(system.file("ex/lux.shp", package="terra"))
roads <- as.lines(v)
rs <- rast(v)
Solution
values(rs) <- 1:ncell(rs)
names(rs) <- "rast"
rsp <- as.polygons(rs)
rp <- intersect(roads, rsp)
rp$length <- perim(rp) / 1000 #km
x <- tapply(rp$length, rp$rast, sum)
r <- rast(rs)
r[as.integer(names(x))] <- as.vector(x)
plot(r)
lines(roads)

How to find area (in hectares) of a raster in R

I am trying to find the area of my raster as shown:
#reading in my raster
abvco2=raster("Avitabile_AGB_Map.tif")
#clipping it to Indonesia
abvco2new=mask(abvco2,Indonesia)
#finding the area
area=area(abvco2new)
However, area() is not helpful as it does not return me with a single area value.
Thank you.
The area function is to compute cell sizes for lon/lat data. From what you say that does not apply to your case. All cells have the same size, so the area of the raster x is
ncell(x) * prod(dim(x)[1:2])
Here is a minimal reproducible example
library(raster)
f <- system.file("external/test.grd", package="raster")
x <- raster(f)
# area of one cell
aone <- prod(dim(x)[1:2])
# total area
ncell(x) * aone
# 84640000
If you want to exclude some areas (e.g. NA) you can use cellStats or zonal
Area excluding NA
b <- cellStats(!is.na(x), sum)
b * aone
#[1] 29237600

How to subset a raster based on grid cell values

My following question builds on the solution proposed by #jbaums on this post: Global Raster of geographic distances
For the purpose of reproducing the example, I have a raster dataset of distances to the nearest coastline:
library(rasterVis); library(raster); library(maptools)
data(wrld_simpl)
# Create a raster template for rasterizing the polys.
r <- raster(xmn=-180, xmx=180, ymn=-90, ymx=90, res=1)
# Rasterize and set land pixels to NA
r2 <- rasterize(wrld_simpl, r, 1)
r3 <- mask(is.na(r2), r2, maskvalue=1, updatevalue=NA)
# Calculate distance to nearest non-NA pixel
d <- distance(r3) # if claculating distances on land instead of ocean: d <- distance(r3)
# Optionally set non-land pixels to NA (otherwise values are "distance to non-land")
d <- d*r2
levelplot(d/1000, margin=FALSE, at=seq(0, maxValue(d)/1000, length=100),colorkey=list(height=0.6), main='Distance to coast (km)')
The data looks like this:
From here, I need to subset the distance raster (d), or create a new raster, that only contains cells for which the distance to coastline is less than 200 km. I have tried using getValues() to identify the cells for which the value <= 200 (as show below), but so far without success. Can anyone help? Am I on the right track?
#vector of desired cell numbers
my.pts <- which(getValues(d) <= 200)
# create raster the same size as d filled with NAs
bar <- raster(ncols=ncol(d), nrows=nrow(d), res=res(d))
bar[] <- NA
# replace the values with those in d
bar[my.pts] <- d[my.pts]
I think this is what you are looking for, you can treat a raster like a matrix here right after you d <- d*r2 line:
d[d>=200000]<-NA
levelplot(d/1000, margin=FALSE, at=seq(0, maxValue(d)/1000, length=100),colorkey=list(height=0.6), main='Distance to coast (km)')
(in case you forgot: the unit is in meters so the threshold should be 200000, not 200)

Get all (multiple) values of a data.frame falling into every raster cell

I have spatial data with lat/long (x/y) and want to put a raster on it. I want to get all values inside every raster cell where the respective points fit into. The points are not equally distributed so one raster cell does not contain the same amount of points as the neighbouring raster cell. I know that there is the function rasterize that uses the mean to average all values inside that cell into one new value but I dont want to interpolate the mean inside the cell, I want to extract all values (here values of points inside that cell).
How can I do this in an effective way?
consider I have:
library(raster)
library(sp)
my data:
x <- runif(n) * 360 - 180
y <- runif(n) * 180 - 90
n <- 1000
values=runif(n)
xy <- cbind(x,y)
my raster
r <- raster(ncols=10, nrows=10)
Now I dont want to average all values like using rasterize, but extract all values (e.g into a list) that fall into that cell.
Many thanks for ideas and help! Is there any function for this?
Firstly, you have to have values in the raster to be sampled. In your example you are just trying to sample an empty raster. ( I mistook this for your sample size in the originals edit; issue is with your example, not the question)
To answer your question...
extract() is the function you are looking for:
library(raster)
library(sp)
r <- raster(ncols=10, nrows=10)
n <- 1000
x <- runif(n) * 360 - 180
y <- runif(n) * 180 - 90
values=runif(n)
r[]<-values
xy <- SpatialPointsDataFrame(data=data.frame(cbind(x,y)),coords=cbind(x,y))
r0 <- extract(r, xy)
plot(r0)

Resources