Create spatial objects in R useful for coordinates() and spsample() - r

I'm trying to use this code, adapted from dataset meuse
data<-list(var1,var2,x,y)
coordinates(data)=~x+y
grid = spsample(data, type = "regular", cellsize = c(0.05,0.05))
vt <- variogram(var1 ~ var2,data=data)
vt.fit <- fit.variogram(vt, vgm(0.2, "Sph", 800, 0.05))
gstatobj <- gstat(id = 'var1', formula = var1 ~ var2, model=vt.fit, set = list(gls=1))
My goal is creating a grid, like meuse.grid. But coordinates doesn't work... list isn't the right command.
What shall I use?
Is correct the way I'm using to create the grid?

the following reproducible example shows jlhoward's comment is right, and Darko's reply is wrong:
library(gstat)
var1 = 1:3; var2 = 1:3; x = 1:3; y = 1:3
data<-list(var1,var2,x,y)
coordinates(data) = ~x+y
Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘coordinates<-’ for signature ‘"list"’
data<-data.frame(var1,var2,x,y)
coordinates(data) = ~x+y
class(data)
[1] "SpatialPointsDataFrame"
attr(,"package")
[1] "sp"
you may have been confused by doing this again, which would give:
coordinates(data) = ~x+y
Error in `coordinates<-`(`*tmp*`, value = ~x + y) :
setting coordinates cannot be done on Spatial objects, where they have already been set
but leaves the existing (and correct) data in tact.

Related

R - extract part of .nc file and convert into raster (similar to WorldClim format)

I have a netcdf file I made which contains percentage values.
The file has 1 variable, 5 dimensions and 0 NetCDF attributes.
The dimensions are
"lon" "lat" "month" "CR" "yearSumm"
They were created using
lon <- ncdim_def("lon", "modis_degrees", -179.5:179.5, unlim=FALSE,
create_dimvar=TRUE, calendar=NA, longname="Longitude")
lat <- ncdim_def("lat", "modis_degrees", -89.5:89.5, unlim=FALSE,
create_dimvar=TRUE, calendar=NA, longname="Latitude")
month <- ncdim_def("month", "month_name", 1:13, unlim=FALSE,
create_dimvar=TRUE, calendar=NA, longname="Month.and.Annual.Data")
CR <- ncdim_def("CR", "CR_numeric", 1:12, unlim=FALSE,
create_dimvar=TRUE, calendar=NA, longname="Cloud.Regime")
yearSumm <- ncdim_def("yearSumm", "yearOrSummType", 1:21, unlim=FALSE,
create_dimvar=TRUE, calendar=NA, longname="Year.and.Summary.Data")
I want to extract 13 layers (each latxlong with each cell a percentage value) from this and make them into a raster file like the bioclimatic data you can download from worldclim
I have tried extracting the data I want into an array, to then make a raster. I did that using
CR_RFO <- ncvar_get(CRnc, attributes(CRnc$var)$names[1])
CR_Ann <- as.array(CR_RFO[1:360, 1:180, 13, 1:12, 18])
This seems to have selected the data I want.
I then tried to make that into raster format.
raster(CR_Ann)
Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘raster’ for signature ‘"array"’
> CR_R <- as.raster(CR_Ann)
Error in array(if (d[3L] == 3L) rgb(t(x[, , 1L]), t(x[, , 2L]), t(x[, :
a raster array must have exactly 3 or 4 planes
> CR_R <- raster(CR_Ann)
Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘raster’ for signature ‘"array"’
> CR_R <- stack(CR_Ann)
Error in data.frame(values = unlist(unname(x)), ind, stringsAsFactors = FALSE) :
arguments imply differing number of rows: 777600, 0
> CR_R <- brick(CR_Ann)
Eventually brick worked, but I don't think that is actually what I want.
When I looked up the WorldClim files I downloaded, it is a zip file of .tifs
I also had tried
# set path and filename
ncpath <- "data/"
ncname <- "CR_RFO"
ncfname <- paste(ncpath, ncname, ".nc", sep="")
dname <- "Ann" # note: Ann means Annual
CR_raster <- brick(ncfname, varname="CR_RFO")
CR_raster; class(CR_raster)
which resulted in the error
CR_RFO has more than 4 dimensions, I do not know what to do with these data
I suspect I am going about it from the wrong angle, and maybe even have made my netcdf file incorrectly, as lat and long are not variables like in some of the examples I have read.
How can I extract these 13 lat x long layers and output them as .tif as per worldclim?
This is how I have ended up doing what I think I needed to. I haven't tested this in place of worldclim data yet, but I have successfully made the geotiff files.
CRnc <- nc_open("data/CR_RFO.nc")
CR_RFO <- ncvar_get(CRnc, attributes(CRnc$var)$names[1])
Repeat from here for each tif I want, selecting the correct number in the 4th place in the index, and changing the file names accordingly.
CR1_Ann <- as.matrix(CR_RFO[1:360, 1:180, 13, 1, 18])
CR1_Ann <- t(CR1_Ann)
CR1_Ann <- flipud(CR1_Ann)
CR1_Annr <- raster(CR1_Ann, ymn = -89.5, ymx = 89.5, xmn = -179.5, xmx = 179.5)
#plot(CR1_Annr)
writeRaster(CR1_Annr, "./data/CR_Ann/CR1_Ann", format = "GTiff")
This is not an elegant solution, so if anyone has a better way, please share.

Extracting elevation data with getData in the Raster package

I am trying to get some elevations for bird locations I have in NZ. I thought I might use the code provided as an answer to a similar question (Extracting elevation from website for lat/lon points in Australia, using R), unfortunately I get errors when using the extract function in the raster package, even though the code is almost identical.
library(raster)
m <- data.frame(lon = c(172.639847, 173.283966), lat = c(-43.525650, -41.270634))
x <- getData('alt', country = "NZL")
cbind(m, alt = extract(x, m))
plot(x)
points(m)
ERROR:
cbind(m, alt = extract(x, m))
Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘extract’ for signature ‘"list", "data.frame"’
Can anyone tell me what is going wrong? I have been searching for hours but cannot find a solution.
Thanks, Sam
I don't know exactly why, but the subtle reason is that, compared to Australia, getData returns a different data structure for New Zealand. It returns a list, where the RasterLayers are in the first (and second) list element:
library(raster)
## Australia ==============
m <- data.frame(lon = c(146.9442, 146.4622), lat = c(-36.0736, -36.0491))
aus <- getData('alt', country = "AUS")
class(aus)
# [1] "RasterLayer"
# attr(,"package")
# [1] "raster"
cbind(m, alt = extract(aus, m))
## New Zealand ============
m <- data.frame(lon = c(172.639847, 173.283966), lat = c(-43.525650, -41.270634))
nzl <- getData("alt", country = "NZL")
> class(nzl) # is a list!
# [1] "list"
> class(nzl[[1]])
# [1] "RasterLayer"
# attr(,"package")
# [1] "raster"
cbind(m, alt = extract(nzl[[1]], m))
cbind(m, alt = extract(nzl[[2]], m))

Create empty spatial lines object

I am trying to create an empty SpatialLines object. With polygons it is easy:
SpatialPolygons(list())
For spatial lines this does not work:
SpatialLines(LinesList = list())
Error in bb[1, ] : incorrect number of dimensions
SpatialLines(LinesList = Lines(list(),ID = "a"))
Error in as.list.default(X) :
no method for coercing this S4 class to a vector
SpatialLines(LinesList = Lines(slinelist = Line(coords = cbind(x = c(), y = c())), ID = c()))
Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘coordinates’ for signature ‘"NULL"’
Does someone know how it I could create an empty SpatialLines object?
Workaround
I found a workaround which is maybe not the best way of doing it. I generates a spatial line with no length:
SpatialLines(list(Lines(Line(coords = cbind(x = c(0,0), y = c(0,0))), ID = "A")))
Interesting Q!
The only way I was able to work around was by creating a dummy line and removing it like this:
sl <- SpatialLines(LinesList = list(Lines(Line(matrix(0, ncol = 2)), ID = NA)))
sl <- sl[0]
length(sl)
# [1] 0
When adding your dummy line the length is returned as 1 as expected:
length(rbind.SpatialLines(sl, SpatialLines(list(Lines(Line(coords = cbind(x = c(0,0),
y = c(0,0))),
ID = "A")))))
# [1] 1

Minimum elevation within km

Trying to find the minimum elevation within 10km of a certain latitude and longitude using R.
So far I have
dem <- getData("SRTM", lat=42.90, lon=-78.85, path = datadir)
plot(dem)
I know I need to create spatial points and eventually buffer/extract the information.
When I try:
buffdem <- buffer(dem, width=10000)
It does not work because I don't have any points.
I tried
dem <- getData("SRTM", lat=42.90, lon=-78.85, path = datadir)
coords <- data.frame(
x = rnorm(100),
y = rnorm(100)
)
coordinates(dem)
spdf = SpatialPointsDataFrame(coords, dem)
I get the following error:
Error in validObject(.Object) : invalid class
“SpatialPointsDataFrame” object: invalid object for slot "data" in
class "SpatialPointsDataFrame": got class "RasterLayer", should be or
extend class "data.frame"
I think this accomplishes what you need:
library(raster)
#elevation <- getData("SRTM", lat=42.90, lon=-78.85)
#poi <- cbind(lon=-78.85, lat=42.90)
using a smaller example data set for quicker download:
elevation <- getData('alt', country='CHE')
poi <- cbind(8.13, 46.47)
e <- extract(elevation, poi, buffer=10000)
sapply(e, min, na.rm=TRUE)
By the way, this is a duplicate of this and this question.

autokrige and proj4string

I am using the R function autokrige from automap package, but I got an error and I do not know how to solve it. Do you have any hints?
Thank you!
sp.poidf <- SpatialPointsDataFrame(sp.poi,thresh.df)
proj4string(sp.poidf) <- CRS("+proj=longlat +datum=WGS84")
pro.df=spTransform(sp.poidf, CRS("+proj=merc +zone=32s +datum=WGS84"))
sp.new <- SpatialPoints(new.poi)
proj4string(sp.new) <- CRS("+proj=longlat +datum=WGS84")
pro.new <- spTransform(sp.new, CRS("+proj=merc +zone=32s +datum=WGS84"))
mykri <- autoKrige(mythresh~1,pro.df,newdata=pro.new)
Error in function (classes, fdef, mtable) :
unable to find an inherited method for function "proj4string", for signature "NULL"
The following code reproduces your problem:
require(automap)
require(rgdal)
loadMeuse()
proj4string(meuse) = CRS("+init=epsg:28992")
proj4string(meuse.grid) = CRS("+init=epsg:28992")
meuse = spTransform(meuse, CRS("+proj=merc +zone=32s +datum=WGS84"))
# Note that meuse.grid no longer is a grid due to the reprojection
meuse.grid = spTransform(meuse.grid, CRS("+proj=merc +zone=32s +datum=WGS84"))
kr = autoKrige(zinc~1, meuse, newdata = meuse.grid)
Error in function (classes, fdef, mtable) :
unable to find an inherited method for function "proj4string", for signature "NULL"
The problem is that you use newdata =, while you should be using new_data = (note the underscore). The following code runs fine:
kr = autoKrige(zinc~1, meuse, new_data = meuse.grid)
The documentation of autoKrige shows this, but krige (from gstat) uses newdata, so I understand the confusion.
What goes wrong is that newdata = is not recognized by autoKrige, and put in the ... part of the argument list. When autoKrige calls krige there is a conflict between new_data supplied by autoKrige, and newdata supplied via .... To prevent other users from ending up with the rather vague error message, I added a check to automap. The erroneous code now leads to an exception:
> kr = autoKrige(zinc~1, meuse, newdata = meuse.grid)
Error in autoKrige(zinc ~ 1, meuse, newdata = meuse.grid) :
The argument name for the prediction object is not 'newdata', but 'new_data'.

Resources