how to run savitzkey Golay filter on time series NDVI image - r

Is there any way to run savitzky golay filter on time series NDVI image in R. I had already tried with the following code given in the package 'signal';
sg <- sgolayfilt(timeseries,3,5).
But it returns following error;
Error in if (all(is.na(x))) return(x) :
argument is not interpretable as logical
The file "timeseries" here is a stacked raster NDVI image. Can anybody help me in this regard.
Thank you for your kind help.

I have 12 raster layers, then I stack them into raster stack
###### Load needed package
library(raster)
library(sp)
library(rgdal)
library(tiff)
library(ggplot2)
library(maptools)
library (zoo)
library (signal)
library(timeSeries)
NDVI_STACK <- stack (jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec)
fun <- function(x) {
v=as.vector(x)
z=substituteNA(v, type="mean") # from package timeSeries
NDVI.ts2 = ts(z, start=c(2005,1), end=c(2005,12), frequency=12)
x=sgolayfilt(NDVI.ts2, p=2, n=5, ts=30)
NDVI.filtered <- calc(NDVI_STACK, fun, progress='text') #raster calculation process ......
You may need to adjust p and n depending on your data. BTW, n must be odd dimension and, from my experience, p is less than n
: This link is very useful
I hope it could help:)

Related

Raster calculation in R

I have two files from these website:
https://sedac.ciesin.columbia.edu/data/set/gpw-v4-population-count-rev11/data-download
And a shapefile of China from these website
https://gadm.org/download_country_v3.html
I would like to compute the difference between the raster population layers, that I can show a map where each pixel represents the change in the population in China.
I used this code
library(raster)
library(sf)
library(tmap)
p_15 <- terra::rast("gpw-v4-population-count-rev11_2015_2pt5_min_tif/gpw_v4_population_count_rev11_2015_2pt5_min.tif")
p_20 <- terra::rast("gpw-v4-population-count-rev11_2020_2pt5_min_tif/gpw_v4_population_count_rev11_2020_2pt5_min.tif")
CHN <- sf::read_sf("gadm36_CHN_shp/gadm36_CHN_1.shp")
CHN <- sf::st_transform(CHN, crs="epsg:4490")|> terra::vect()
p_15<- terra::project(p_15,'EPSG:4490')
p_20 <- terra::project(p_20,'EPSG:4490')
p_15_crop <- terra::crop(p_15, CHN)
p_20_crop <- terra::crop(p_20, CHN)
p_15_mask <- mask(p_15_crop, CHN)
p_20_mask <- mask(p_2_crop, CHN)
The code above everything works fine.
Now I used overlay from the raster package to calculate the difference between the population layers to show the change in each pixel.
I gave these code
diff1520 <- overlay(p_15_mask, p_20_mask, fun=function(x,y){return(y-x)})
But I got the error message method not applicable??? What is wrong with the code?
By the way, I also used geodata package, but did not solve my problem
Simply subtracting the objects will work. But if you still want to apply a function to a SpatRaster, you can use terra::lapp, which is equivalent to raster::overlay. The main difference is that you have to combine the layers first.
library(terra)
p_mask <- c(p_15_mask, p_20_mask)
diff1520 <- lapp(p_mask, fun=function(x,y){return(y-x)})
It's probably because you created your masks with terra. So the masks are SpatRast objects and you tried to use the overlay() function from raster and that only works with raster objects.
You can do what you want with
diff1520 <- p_20_mask - p_15_mask
That's the basic terra way.

Error in Merging two shape files (a spatial polygons and spatial points) in R

My goal is to combine two shapefiles and extract the combined variables. However, I am getting the following error when I am trying to combine the two files: Error in as.vector(x): no method for coercing this S4 class to a vector
Below is my code:
#libraries
library(rgdal)
library(sp)
library(arulesViz)
library(rgdal)
library(raster)
library(maptools)
DHSshp <- readOGR("MWGE7AFL.shp")
district <- readOGR("mwi_admbnda_adm2_nso_20181016.shp")
summary(DHSshp)
summary(district)
is(DHSshp)
is(district)
subs_union <- union(DHSshp, district)
OR
pts.poly <- point.in.polygon(DHSshp, SAshp)
I failed to rule out that error after trying different ways around, I am hopeless. Please help
I hope this concern could be overcome by using the function
point.in.poly() of an r package 'SpatialEco',
i.e, use
SpatialEco::point.in.poly(DHSshp, district).
Regards!

How to create moving window filter of semivariogram outputs in R using focal area function?

I'm trying to create a raster filled with semivariogram outputs such as the sill and range of an area which describes the spatial autocorrelation. I wanted to try using the focal function in R as a way to scan an area, and the variogram function from gstat package to calculate sill and range.
I've tried the following code, but there are issues with the function.
library(raster)
library(gstat)
r <- raster()
r[] <- 1:ncell(r)
ra <- aggregate(r, 5)
plot(ra)
v<-variogram(layer~1,as(ra,"SpatialPixelsDataFrame"))
plot(v)
f = fit.variogram(v, vgm("Sph"))
f$psill[2]
f$range
var.sill<-function(x){
names(x)<-c("layer")
v<-variogram(layer~1,as(x,"SpatialPixelsDataFrame"))
f = fit.variogram(v, vgm("Sph"))
f$psill[2]
}
var.sill(ra)
# 374758092
## in a window surrounding each focal cell
rpsill <- focal(ra, w=matrix(1/225, ncol=15, nrow=15), fun=var.sill)
plot(rpsill)
The error states," Error in as(x, "SpatialPixelsDataFrame") :
no method or default for coercing “numeric” to “SpatialPixelsDataFrame” "
I would appreciate any help with this or if there is another way to potential create these new rasters please let me know too.
Thank you.

unwanted subgeometries when converting raster to polygons

I am converting many rasters to polygon. But in quite a few cases, I am seeing unexpected subgeometries, and I can't seem to get rid of them.
This is with R v3.3.3 and raster package v2.5-8.
Here is an example that should reproduce the problem I am having.
You can download the raster that I use here.
# first, read in raster and coarsen to something more manageable
library(raster)
library(rgeos)
env <- raster('adefi.tif')
env2 <-aggregate(env, 8)
# Reclassify such that cells are either 1 or NA
env2[!is.na(env2)] <- 1
# this is what the raster now looks like:
plot(env2)
# Now I convert to polygon, choosing to dissolve
p <- rasterToPolygons(env2, dissolve=T)
plot(p)
# I find that I can't get rid of these subgeometries
p <- gUnaryUnion(p) # identical result
gIsValid(p) # returns TRUE
I'm not sure where the problem is... Is it in how the raster package converts to cell polygons? Or is it how the rgeos package dissolves those cell polygons together?
Is there a work-around?
It looks like a projection issue. This works for me:
library(raster)
library(rgeos)
env <- raster(file.path(fp, "adefi.tif"))
env2 <- aggregate(env, 8)
env2[is.na(env2) == F] <- 1
# Project Raster
proj_env2 <- projectRaster(env2, crs = CRS("+init=epsg:3577"))
p <- rasterToPolygons(proj_env2, dissolve = T)
plot(p)
Not sure why the need for reprojection since epsg:3577 looks to be the same as the original projection, but I usually confirm projection using proj4string() or spTransform() to make sure everything will line up.

Error when attempting distance() with raster

I have been trying to get a graph from using distance() in the raster package. The raster dimensions are inherited from a SpatialPointsDataFrame. The raster works fine until I try distance(raster) and get the following warning:
Warning message:
In matrix(v, ncol = tr$nrows[1] + 3) :
data length [8837790] is not a sub-multiple or multiple of the number of rows [4384]
The bizarre thing is the raster works at smaller resolution but not large. The error can be replicated below:
Fails:
library(raster)
r <- raster(ncol=4386,nrow=6039)
r[] <- NA
r[500] <- 1
dist <- distance(r)
plot(dist / 1000)
Works:
r <- raster(ncol=438.6,nrow=603.9)
r[] <- NA
r[500] <- 1
dist <- distance(r)
plot(dist / 1000)
Why? Have I missed something really obvious?
An update to raster_2.4-20 solved the problem. Thanks Pascal and RobertH for pointing me in the right direction.

Resources