I'd like to calculate the percentual 1´s presence in a binomial raster using circular area using a sf object (buffer arond points). I have tried to use the extract function but I am not able to create a final correct object. I try to:
# Packages
library(sf)
library(raster)
library(ggplot2)
# Create some points
set.seed(1)
df <- data.frame(
gr = c(rep("a",5),rep("b",5)),
x = rnorm(10),
y = rnorm(10)
)
df <- st_as_sf(df,coords = c("x","y"),remove = F, crs = 4326)
df.laea = st_transform(
df,
crs = "+proj=laea +x_0=4600000 +y_0=4600000 +lon_0=0.13 +lat_0=0.24 +datum=WGS84 +units=m"
)
# Create abinomial values raster
r <- raster(extent(df.laea) + 3, resolution=1000)
values(r) <- rep(c(1,0),times=length(r)/2)
r.df <- as.data.frame(r, xy = TRUE)
# Buffer around the points
sample.area <- st_buffer(df.laea,dist=10000)
sample.area$area <- rnorm(n=nrow(sample.area),mean=22)
ggplot() +
geom_raster(data = r.df,
aes(x = x, y = y, fill = layer)) +
geom_sf(data = sample.area, fill = "white", color = "white") +
geom_sf(data = df.laea,color = "red")
#Function for extract percentual 1s
perc1<- function(x,...) {
leng1<-length(which(x==1)) # length of 1s pixels
lengtotal<-length(na.omit(x)) # total length of pixels inside each circular sample
perc<-(leng1/lengtotal)
return(perc)
}
res <- NULL
for (s in 1: length(sample.area)){
# Extract inside ech circular buffer
square_cc <- raster::extract(r, # raster layer
sample.area[s], # spatial polygon for extraction
fun=perc1, # what to value to extract
df=TRUE, na.rm = FALSE) # return a dataframe
res <- rbind(res,c(s,square_cc))
}
#
res
# ID layer
# [1,] integer,10 numeric,10
# [2,] integer,10 numeric,10
# [3,] integer,10 numeric,10
# [4,] integer,10 numeric,10
# [5,] integer,10 numeric,10
And I'd like as output something like this and if have any NA's (outside the area) I need to remove it:
s area square_cc
1 22.91898 0.56230
...
6 -0.3053884 0.59390132 0.73221
In my example, I loose 3 circular areas a cause of NA's or circle outside the raster. Please, any help with it?
Since you only have 0 and 1 values, you can compute the mean to get the fraction of cells that is 1 (when ignoring NAs).
You can do that like this:
library(terra)
set.seed(1)
v <- vect(cbind(x= rnorm(10), y = rnorm(10)), crs="+proj=longlat")
v <- project(v, "+proj=laea +x_0=4600000 +y_0=4600000 +lon_0=0.13 +lat_0=0.24 +datum=WGS84 +units=m")
r <- rast(ext(v) + 3, res=1000, crs=crs(v), vals=c(1,0))
b <- buffer(v, 10000)
e <- extract(r, b, mean, na.rm=TRUE)
# if the buffer is small relative to the raster cells size
e <- extract(r, b, mean, na.rm=TRUE, exact=TRUE)
As expected for this raster, the values are all close to 0.5
head(e)
# ID lyr.1
#1 1 0.5028999
#2 2 0.5000373
#3 3 0.5020881
#4 4 0.5036896
#5 5 0.5012382
#6 6 0.4996306