How to fill in missing/NA values in raster with terra package? - r

I have a DEM raster that has small holes (i.e. NAs) in it that I would like to fill, without altering any of the non-NA values. After reading about a solution suggested for the raster package, I tried using terra's focal function with the following arguments: focal(m, w=9, fun=mean, NAonly=T, na.rm=T). While this did mostly fill the hole, it appears that the surrounding data was slightly "smoothed" suggesting that the function did not limit itself to only filling NA values (the images below show before and after images).
Does the NAonly=T argument still apply in terra as it did in raster? Or is there a better way to fill holes without chaning non-NAs in terra?
DEM prior to applying focal function (yes, the hole was partially filled already)
DEM after applying focal function. Note the overall smoother appearance of the DEM.

It looks like argument for terra is na.policy="only" rather than NAonly=TRUE used in raster. So focal(m, w=9, fun=mean, na.policy="only", na.rm=T) solves this issue. It's slight "boxier" than some other methods that I have used but otherwise it did the job.
I have also noticed that the output raster is moved by ~1/2 the focal window width but I have posted a question here about solving that issue.
UPDATE:
As of 1.5.27 this bug has been fixed.

Related

Weird streaks when working with a large Raster

I have a large elevation raster from the ASTER database made by using raster::mosaic(). Each tile represents a one-degree by one-degree portion of the earth with an estimated raster resolution of 30m^2. I include the code that I used to mosaic them below, but I don't believe that it is the problem.
Mosaic <- do.call(mosaic,c(list of rasters, tolerance = 1, fun=mean)
Once that is run, I get the following elevation tif, which you can DOWNLOAD HERE.
I then measure the topographic ruggedness using raster::terrain(), using theTerrain Ruggedness Index as my method:
TRI <- terrain(Mosaic, opt="TRI")
This yields:
As you can see, there are faint streaks in the map which I cannot explain. Due to the full extent of my study, I need to aggregate this raster to a coarser resolution. Therefore I use the aggregate function in the raster package as well.
TRI_Agg <- aggregate(TRI,fact = 255, fun = mean)
This yields the following raster.
Here you can see that the streaks are much more pronounced and fairly consistent throughout the whole map. I tried doing this with other study areas and the problem persisted (i.e this would happen with raster tiles all around the world). I can't explain why those streaks are occurring. I have attempted different ways of going about this which include doing a neighborhood analysis (to fill in missing values if any) and processing the tiles before mosaicing them together. None of these have worked.
When I aggregate the raster before, the roughness calculation, the streaks do not appear which makes me believe this issue arises when using aggregate(). However, for my specific research question, I cannot calculate TRI using an aggregated raster.

How to get raster file from a nested raster list produced by landscapemetrics package in R?

Package landscapemetrics can calculate area of each patch for a given raster file, shape of that patch and so on. I want to have not only tibble-frame with patch metrics calculated, but a new raster where each pixel within specific patch will have a value of the area of that patch, shape indicator and so on. We can do it with function spatialize_lsm() (it produces a Large list nested object with probably RasterObject objects within):
library(landscapemetrics)
plot(podlasie_ccilc) # this raster data is provided with package
podlasie.metrics.area <- spatialize_lsm(podlasie_ccilc, what = 'lsm_p_area') # creates a list
plot(podlasie.metrics.area) # produces an error...
How to get a desirable raster file with patch metrics from that list? I guess it is a question of raster package or something else, since landscapemetrics documentation tells nothing about this step.
I not that this data and new raster do not have resolution of the pixel like in meters (30, 30 for Landsat satellite image, for example). So we cannot plot the new raster produced:
podlasie.metrics.area[[1]]
plot(podlasie.metrics.area[[1]])
So I guess landscapemetrics cannot deal with such rasters, we can even use its function to check a suitability of the prior raster for patch discovering:
check_landscape(podlasie_ccilc)
Upd. I did it for the Landsat dataset with resolution 30, 30 and it produced patch area raster, but again I cannot open/show/save as raster it, because of the same error.
Package maintainer helps to solve a problem (yes, it is just related to the structure of list):
plot(podlasie.metrics.area[[1]]$lsm_p_area)

How to stop fortify from merging overlapping polygons

I have a SpatialPolygonsDataFrame containing multiple polygons that I want to plot in ggplot2. However, when I try converting my SpatialPolygonsDataFrame to a dataframe (required by ggplot2) via the fortify {ggplot2} function, polygons that overlap are merged. I know this is where the problem is because View(as.data.frame(data_pre_fortify)) and View(data_post_fortify) tell me the number of polygons before & after fortifying.
Currently my fortify function simply calls fortify(data_post_fortify, region = "id").
Can this merging of polygons be avoided, and if so, how?
Whilst this is by no means a perfect solution, I have managed to work around the issue by creating three SpatialPolygonsDataFrames, each containing only polygons that don't overlap (so overlapping polygons are split between different SpatialPolygonsDataFrames, and then fortifying these on their own. When it came to plotting I therefore had three geom_polygon layers, each calling one of the dataframes containing a subset of polygons.
I realise this isn't a great solution — colour/fill aesthetics cannot be added for all polygons together, plus this manual sorting of overlapping polygons may not be very time effective for larger/more overlapping datasets — so any further answers are very welcome!

writeRaster function in R is automatically setting (unwanted) maximum value, can I set the max value to null?

I am running into a problem with the "writeRaster" function in the raster package in R. I am importing a raster (TIF) that I made in ArcGIS (a distance to feature raster).
My goal was to resample the distance raster to the correct resolution and extent, then "mask" it with the appropriate raster to crop it to the shape I require. When I check the results of the mask with the basic plot function, everything looks great and I can see that each pixel in the new masked raster has a distance value.
However, when I write this raster to a file using the writeRaster function, the resulting raster looks like "swiss cheese" and has missing values for any distance over 35km. After much reading, I cannot find any documentation to suggest that there is a way to modify the maximum value set by writeRaster---or that it should even be setting a max value. I have included my code and the basic plots below. A big thank you to anyone who attempts to help me with this!
#Read in distance to fresh water raster
distFW <- raster("D:/Academia/Arc Data/Grackle/NicaCR_90mlayers/dist_FW.tif")
[plot(distFW)][1]
#Resample this layer to the desired resolution and template
NiCR_DistFW<-as.integer(resample(distFW,NiCRrast.tmpl,method="ngb"))
#essentially the same as the first plot
[plot(NiCR_DistFW)][2]
#Mask the resampled raster to the desired shape
NiCR.DistFW.mask.utm <- mask(NiCR_DistFW,NiCR_Mask) #with CA countries cut out.
[plot(NiCR.DistFW.mask.utm)][3]
#write raster to file (this is where things get weird)
writeRaster(x=NiCR.DistFW.mask.utm, filename='DistFWmask2.tif', format='GTiff', datatype='INT2S') #a way to ensure INT2S
#read the newly written raster file in to R so we can review it
dFW <-raster("DistFWMask2.tif")
[plot(dFW)_writeRaster_result][4]
[1]: https://i.stack.imgur.com/v9RkK.jpg
[2]: https://i.stack.imgur.com/v2DG3.jpg
[3]: https://i.stack.imgur.com/cCwJe.jpg
[4]: https://i.stack.imgur.com/MjWj7.jpg
As you can see from plot 4, an undesirable max value has been set. I was the raster I write to file to look like the one in plot 3, not plot 4.
Thanks in advance for any advice.
Well friends, after taking an hour to detail my question I managed to figure out the answer myself. It had to do with setting the datatype.
INT2S has a maximum value of 32,767
by switching it to INT4S, I capture the full range of values in my raster.
Problem solved!

Autokriging spatial data

I'm trying to use a kriging function to create vertical maps of chemical parameters in an ocean transect, and I'm having a hard time getting started.
My data look like this:
horiz=rep(1:5, 5)
depth=runif(25)
value = horiz+runif(25)/5
df <- data.frame(horiz, depth, value)
The autoKrige function in the automap package looks like it should do the job for me but it takes an object of class SpatialPointsDataFrame. As far as I can tell, the function spTransform in package rgdal creates SpatialPointsDataFrame objects, but there are two problems:
OSX binaries of this aren't available from CRAN, and my copy of RStudio running on OXS 10.7 doesn't seem to be able to install it, and
This function seems to work on lat/long data and correct distance values for the curvature of the Earth. Since I'm dealing with a vertical plane (and short distances, scale of hundreds of meters) I don't want to correct my distances.
There's an excellent discussion of kriging in R here, but due to the issues listed above I don't quite understand how to apply it to my specific problem.
I want a matrix or dataframe describing a grid of points with interpolated values for my chemical parameters, which I can then plot (ideally using ggplot2). I suspect that the solution to my problem is considerably easier than I'm making it out to be.
So there a a few question you want answered:
The spTransform function does not create SPDF's, but transforms between projections. To create a SPDF you can use a simple data.frame as a start. To transform df to a SPDF:
coordinates(df) = c("horiz", "depth")
OS X binaries of rgdal can be found at http://www.kyngchaos.com. But I doubt if you need rgdal.
spTransform can operate on latlong data, but also on projected data. But I do not think you need rgdal, or spTransform, see also point 1.
After you create the SPDF using point 1, you can use the info at the post you mentioned to go on.

Resources