Missing Values After Applying Mask Function - r

I have a raster called 'xx' and is the output from using the 'Distance' function within R Raster. As part of running the distance function, the ocean/sea surrounding my island has been set to a value of 0. In order to change this value from 0 back to NA, I have used the function 'Mask' like so:
asdf<-mask(xx,jamaica.raster, filename="distancesurface.asc", prj=TRUE, keepres=TRUE, overwrite=TRUE)
In the above example, jamaica.raster is being used to replace the 0 values with NA. I run the command and plot the result. As expected, it has left my distance surface in place and set the ocean to NA, exactly as I wanted.
After, when I attempt to writeRaster the object 'asdf' I get the error:
Error in .local(.Object, ...) :
Couldn't find data values in ASCII Grid file.
If I get a summary of the objects 'xx' and 'jamaica.raster' before applying 'mask' function, both have a 'values' section like so:
class : RasterLayer
dimensions : 135, 306, 41310 (nrow, ncol, ncell)
resolution : 0.008333333, 0.008333333 (x, y)
extent : -78.49359, -75.94359, 17.59729, 18.72229 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +ellps=WGS84 +no_defs
data source : D:\Dropbox\\...
names : jamaicapc1
values : -3.419589, 14.17305 (min, max)
If I do the same for my new object 'asdf' there are no values- They seem to have gone missing since using the Mask function. For example:
class : RasterLayer
dimensions : 135, 306, 41310 (nrow, ncol, ncell)
resolution : 0.008333333, 0.008333333 (x, y)
extent : -78.49359, -75.94359, 17.59729, 18.72229 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +ellps=WGS84 +no_defs
data source : C:\Users\Simon\Desktop\distancesurface.asc
names : distancesurface
I assume this is expected behaviour so my question is, how can I write my new raster (asdf) to disk? Is there a step I need to carry out before I can use the writeRaster function?
Thanks in advance for any help you may be able to provide.

Related

Unable to do raster operations in R

Hi my raster values for a Raster Layer are the following:
dimensions : 2225, 2286, 5086350 (nrow, ncol, ncell)
resolution : 0.03333146, 0.03333146 (x, y)
extent : -20.86612, 55.32961, -35.40306, 38.75945 (xmin, xmax, ymin, ymax)
crs : +proj=longlat +datum=WGS84 +no_defs
source : solar.tif
names : solar
values : 0, 2855 (min, max)
However whenever I try to do simple raster operations such as:
plot(solar)
It returns this error:
Error in setValues(outras, m) :
could not find symbol "values" in environment of the generic function
Thanks for any help

Merge (mosaic) of rasters changes resolution

I'm merging two MODIS DSR tiles using a R script that I developed, these are the products:
https://drive.google.com/drive/folders/1RG3JkXlbaotBax-h5lEMT7lEn-ObwWsD?usp=sharing
So, I open both products (tile h15v05 and tile h16v05) from same date (2019180), then I open each SDS and merge them together (00h from h15v05 with 00h from h16v05 and so on...)
Visualisation on Panoply (using the merge option) of the two products:
Purple square is the location of the division line that separates the two tiles.
With my code I obtain a plot with pixels with different resolution (and different min/max values) and I don't understand why:
I suspect that the results obtained are due to:
1- Changing from Sinusoidal CRS to longlat WGS84 CRS;
2- Using resample (method ngb) to work with mosaic.
My code is extensive, but here are some parts of it:
# Open scientific dataset as raster
SDSs <- sds(HDFfile)
SDS <- SDSs[SDSnumber]
crs(SDS) <- crs("+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs")
SDSreprojected <- project(SDS, DesiredCRS)
SDSasRaster <- as(SDSreprojected, "Raster")
# Resample SDS based on a reference SDS (SDS GMT_1200_DSR of a first product), I need to do this to be able to use mosaic
SDSresampled <- resample(SDSasRaster,ResampleReference_Raster,method='ngb')
# Create mosaic of same SDS, but first convert stack to list to use mosaic
ListWith_SameSDS_OfGroupFiles <- as.list(StackWith_SameSDS_OfGroupFiles)
ListWith_SameSDS_OfGroupFiles.mosaicargs <- ListWith_SameSDS_OfGroupFiles
ListWith_SameSDS_OfGroupFiles.mosaicargs$fun <- mean
SDSmosaic <- do.call(mosaic, ListWith_SameSDS_OfGroupFiles.mosaicargs)
# Save SDSs mosaic stack to netCDF
writeRaster(StackWith_AllMosaicSDSs_OfGroupFiles, NetCDFpath, overwrite=TRUE, format="CDF", varname= "DSR", varunit="w/m2", longname="Downward Shortwave Radiation", xname="Longitude", yname="Latitude", zname="TimeGMT", zunit="GMT")
Does anyone have an idea of what could be the cause of this mismatch between results?
print(ResampleReference_Raster)
class : RasterLayer
dimensions : 1441, 897, 1292577 (nrow, ncol, ncell)
resolution : 0.01791556, 0.006942043 (x, y)
extent : -39.16222, -23.09196, 29.99652, 40 (xmin, xmax, ymin, ymax)
crs : +proj=longlat +datum=WGS84 +no_defs
source : memory
names : MCD18A1.A2019180.h15v05.061.2020343034815
values : 227.5543, 970.2346 (min, max)
print(SDSasRaster)
class : RasterLayer
dimensions : 1399, 961, 1344439 (nrow, ncol, ncell)
resolution : 0.01515284, 0.007149989 (x, y)
extent : -26.10815, -11.54627, 29.99717, 40 (xmin, xmax, ymin, ymax)
crs : +proj=longlat +datum=WGS84 +no_defs
source : memory
names : MCD18A1.A2019180.h16v05.061.2020343040755
values : 0, 0 (min, max)
print(SDSmosaic)
class : RasterLayer
dimensions : 1441, 897, 1292577 (nrow, ncol, ncell)
resolution : 0.01791556, 0.006942043 (x, y)
extent : -39.16222, -23.09196, 29.99652, 40 (xmin, xmax, ymin, ymax)
crs : +proj=longlat +datum=WGS84 +no_defs
source : memory
names : layer
values : 0, 62.7663 (min, max)
Also, some of the islands were ignored by the script (bottom right)...
sorry I didn't reply earlier. So I think you're right that this issue is extent to which you are resampling. I think you might be able to get around this by creating a dummy raster that has the extent of the raster you want to resample, but has the resolution of the raster you want to mosaic to.Try:
dummy<-raster(ext = SDSasRaster#extent, resolution=ResampledReference_Raster#res, crs=SDSasRaster#crs)
SDS2<-resample(SDSasRaster, dummy, method="ngb")
Final<-moasic(SDS2, ResampledReference_Raster, fun=mean)

How can I get the cell number of a raster using extent information?

I have a raster and I am using the raster package.
class : RasterLayer
dimensions : 103, 118, 12154 (nrow, ncol, ncell)
resolution : 0.008333333, 0.008333333 (x, y)
extent : -83.075, -82.09167, 34.95833, 35.81667 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0
data source : C:\fb.tif
names : fdr_fb
values : 1, 128 (min, max)
I know how to subset and all. But how can I find the cellnumber (preferred) or cellvalue by using the Lat-Long value?
For example, I can find cell value using lat/long:
extract(ras,SpatialPoints(cbind(-82.8,35.2)))
But I want to find the cell number (row,col) corresponding to (Say) Long= -82.1 and Lat= 35.0
Raster: https://www.dropbox.com/s/8nhfirxr2hm3l4v/fdr_fb.tif?dl=0
To get the cell number from a point, you can do:
cellFromXY(ras, cbind(-82.8, 35.2))
If you have an Extent object e you can do:
cellsFromExtent(ras, e)

Using 'disaggregate' with GCM data

I have data from various Global Circulation Models (GCM) that I need in at a finer resolution to perturb climate observations that are 0.5 degree pixel. I saw that I could use disaggregate because this function won't change pixels values, as 'resample' does using, e.g., the bilinear method. But still, the output doesn't match my fine-res-grids.
Here an example with the dimensions of the files I'm dealing with:
r = raster(ncols=720, nrows=360) #fine resolution grid
r[] = runif(1:100)
> r
class : RasterLayer
dimensions : 360, 720, 259200 (nrow, ncol, ncell)
resolution : 0.5, 0.5 (x, y)
extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
data source : in memory
names : layer
values : 0.0159161, 0.9876637 (min, max)
s = raster(ncols=192, nrows=145) #dimensions of one of the GCM
s[] = runif(1:10)
> s
class : RasterLayer
dimensions : 145, 192, 27840 (nrow, ncol, ncell)
resolution : 1.875, 1.241379 (x, y)
extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
data source : in memory
names : layer
values : 0.03861309, 0.9744665 (min, max)
d=disaggregate(s, fact=c(3.75,2.482759)) #fact equals r/s for cols and rows
> d
class : RasterLayer
dimensions : 290, 768, 222720 (nrow, ncol, ncell)
resolution : 0.46875, 0.6206897 (x, y)
extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
data source : in memory
names : layer
values : 0.03861309, 0.9744665 (min, max)
The dimensions of 'd' are not equal to the dimensions of 'r', so I can't do operations with the 2 grids. And I'm not meant to be interpolating the pixel values. So, what's the best method to achieve the disaggregation with GCM data?
Thanks in advance.
The code below should help- it uses aggregate to the closest integer scaling possible then resample to match the other raster's spatial characteristics exactly:
r = raster(ncols=720, nrows=360) #fine resolution grid
r[] = runif(1:100)
s = raster(ncols=192, nrows=145) #dimensions of one of the GCM
s[] = runif(1:10)
d=disaggregate(s, fact=c(round(dim(r)[1]/dim(s)[1]),round(dim(r)[2]/dim(s)[2])), method='') #fact equals r/s for cols and rows
e=resample(d, r, method="ngb")
But there a few caveats/ warnings: If you want to have the same values as the original raster, use disaggregate with method='' or else it will interpolate. But most important looking at the aspect ratio between your r and s rasters, they are not the same: dim(r)[1]/dim(s)[1] != dim(r)[2]/dim(s)[2]). I would double check the original data because if there is a difference in resolution, projection, or extent you will not get what you want from the steps above.

Calculating area of occupancy from a binary unprojected raster

I have a series of binary raster layers (ascii file) showing presence/absence of a species in Europe and Africa. The file is based on unprojected lat/long (WGS84) data. My aim is to calculate the area of presence using R (I don't have access to ArcGIS).
I know that the raster package has a function for calculating area, but I'm worried that this won't be accurate for unprojected data. I have also looked at the cellStats function in the raster package, and can use this to "sum" the number of cells occupied, but I feel this has the same problem.
jan<-raster("/filelocation/file.asc")
jan
class : RasterLayer
dimensions : 13800, 9600, 132480000 (nrow, ncol, ncell)
resolution : 0.008333333, 0.008333333 (x, y)
extent : -20, 60, -40, 75 (xmin, xmax, ymin, ymax)
coord. ref. : NA
data source : "/filelocation"
names : file.asc
values : -2147483648, 2147483647 (min, max)
area(jan)
class : RasterLayer
dimensions : 13800, 9600, 132480000 (nrow, ncol, ncell)
resolution : 0.008333333, 0.008333333 (x, y)
extent : -20, 60, -40, 75 (xmin, xmax, ymin, ymax)
coord. ref. : NA
names : layer
values : 6.944444e-05, 6.944444e-05 (min, max)
Warning messages:
1: In .local(x, ...) :
This function is only useful for Raster* objects with a longitude/latitude coordinates
2: In .rasterFromRasterFile(grdfile, band = band, objecttype, ...) :
size of values file does not match the number of cells (given the data type)
cellStats(jan,"sum")
[1] 3559779
Anybody know of a way to calculate the presence area accurately, accounting for the earth curvature?
Thanks!
I do not know what is going in with your file (why you get warning #2). But is here is a work around
r <- raster(nrow=13800, ncol=9600, xmn=-20, xmx=60, ymn=-40, ymx=75)
# equivalent to r <- raster(jan)
x = area(r)
x
class : RasterLayer
dimensions : 13800, 9600, 132480000 (nrow, ncol, ncell)
resolution : 0.008333333, 0.008333333 (x, y)
extent : -20, 60, -40, 75 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84
data source : c:\temp\R_raster_Robert\2015-01-26_213612_1208_85354.grd
names : layer
values : 0.2227891, 0.8605576 (min, max)
Now you have the area of each cell in km2. By multiplying these values with Raster objects with presence/absence values and then using cellStats( , 'sum') you can obtain the total area with presence.

Resources