Reputation: 192
I typically use Matlab and am only an amateur when it comes to R. I have been trying to use someone elses code from 2011 and it is calling for a function called 'xyValues'. I have found that this used to be function within the Raster package (version 1.5.8) but no longer appears in the current version. The old raster package is incompatible with newer versions of R. I have tried downgrading R but then that causes other issues.
I have downloaded the tar.gz file and extracted the code for the xyValues function. I tried to paste it into my newer version of the Raster package, but unsurprisingly, it didn't work. Is there an easy way for me to turn the code for this function into an actual function that I can save and then use (as if I wrote the function myself)? I could do this easily in matlab, but it seems the process for writing a function is a little different in R and I don't really know where to start? I see some variations of this question on this site, but I'm wondering if it is possible for a new user of R (like me) to be able to do what I am suggesting. Perhaps it is only possible if you have a lot of knowledge regarding R. This is the code I extracted:
# Author: Robert J. Hijmans
# contact: [email protected]
# Date : November 2008
# Version 0.9
# Licence GPL v3
if (!isGeneric("xyValues")) {
setGeneric("xyValues", function(object, xy, ...)
standardGeneric("xyValues"))
}
setMethod("xyValues", signature(object='Raster', xy='SpatialPoints'),
function(object, xy, method='simple', buffer=NULL, fun=NULL, na.rm=TRUE,...) {
callGeneric(object, coordinates(xy), method, buffer, fun, na.rm, ...)
}
)
setMethod("xyValues", signature(object='Raster', xy='data.frame'),
function(object, xy, method='simple', buffer=NULL, fun=NULL, na.rm=TRUE,...) {
callGeneric(object, as.matrix(xy), method, buffer, fun, na.rm, ...)
}
)
setMethod("xyValues", signature(object='Raster', xy='vector'),
function(object, xy, method='simple', buffer=NULL, fun=NULL, na.rm=TRUE, ...) {
if (length(xy) == 2) {
callGeneric(object, matrix(xy, ncol=2), method, buffer, fun, na.rm, ...)
} else {
stop('xy coordinates should be a two-column matrix or data.frame, or a vector of two numbers.')
}
} )
setMethod("xyValues", signature(object='RasterLayer', xy='matrix'),
function(object, xy, method='simple', buffer=NULL, fun=NULL, na.rm=TRUE, ...) {
if (dim(xy)[2] != 2) {
stop('xy has wrong dimensions; it should have 2 columns' )
}
if (! is.null(buffer)) {
if (method != 'simple') { warning('method argument is ignored when a buffer is used') }
return( .xyvBuf(object, xy, buffer, fun, na.rm=na.rm) )
}
if (method=='bilinear') {
return(.bilinearValue(object, xy))
} else if (method=='simple') {
cells <- cellFromXY(object, xy)
return(.readCells(object, cells))
} else {
stop('invalid method argument. Should be simple or bilinear.')
}
}
)
setMethod("xyValues", signature(object='RasterStack', xy='matrix'),
function(object, xy, method='simple', buffer=NULL, fun=NULL, na.rm=TRUE, ...) {
.xyvStackBrick(object, xy, method, buffer, fun, na.rm, ...)
} )
setMethod("xyValues", signature(object='RasterBrick', xy='matrix'),
function(object, xy, method='simple', buffer=NULL, fun=NULL, na.rm=TRUE, ...) {
.xyvStackBrick(object, xy, method, buffer, fun, na.rm, ...)
} )
.xyvStackBrick <- function(object, xy, method='simple', buffer=NULL, fun=NULL, na.rm=TRUE, ...) {
dots <- list(...)
layer <- dots$layer
n <- dots$nl
nls <- nlayers(object)
if (is.null(layer)) { layer <- 1 }
if (is.null(n)) { n <- nls }
layer <- min(max(1, round(layer)), nls)
n <- min(max(1, round(n)), nls-layer+1)
if (dim(xy)[2] != 2) {
stop('xy has wrong dimensions; there should be 2 columns only' )
}
if (! is.null(buffer)) {
if (method != 'simple') { warning('method argument is ignored when a buffer is used') }
return( .xyvBuf(object, xy, buffer, fun, na.rm, layer=layer, n=n) )
}
if (method == 'bilinear') {
result <- .bilinearValue(object, xy, layer=layer, n=n)
return(result)
} else if (method=='simple') {
cells <- cellFromXY(object, xy)
return( cellValues(object, cells, layer=layer, n=n) )
} else {
stop('invalid method argument. Should be simple or bilinear.')
}
}
As a followup to this question, initially, when I wanted to see if this function was in my raster package I tried typing help(xyValues)
and nothing came up (because it didn't exist). However, when I try this for functions that DO exist within the package, they too, are not showing up. Does this mean my raster package isn't loaded correctly?
The piece of code I am using with the function in it is:
elevgrid <- xyValues(elev,cbind(xygrid[,2],xygrid[,1]))
where elev
is a Formal class Rasterlayer of size 920x1000 and xygrid
is 4800 obs of 2 variables (x y coordinates)
I tried using:
> source("C:/Users/Documents/raster/R/xyValues.R")
but I got all these errors:
in method for ‘xyValues’ with signature ‘object="Raster",xy="data.frame"’: no definition for class “Raster”
in method for ‘xyValues’ with signature ‘object="Raster",xy="vector"’: no definition for class “Raster”
in method for ‘xyValues’ with signature ‘object="RasterLayer",xy="matrix"’: no definition for class “RasterLayer”
in method for ‘xyValues’ with signature ‘object="RasterStack",xy="matrix"’: no definition for class “RasterStack”
in method for ‘xyValues’ with signature ‘object="RasterBrick",xy="matrix"’: no definition for class “RasterBrick”
Warning message:
in method for ‘xyValues’ with signature ‘object="Raster",xy="SpatialPoints"’: no definition for classes “Raster”, “SpatialPoints”
I tried the getvalues
and approxNA
functions and got this:
> elevgrid <- getValues(elev,cbind(xygrid[,2],xygrid[,1]))
Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘getValues’ for signature ‘"RasterLayer", "matrix", "missing"’
> elevgrid <- approxNA(elev)
Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘approxNA’ for signature ‘"RasterLayer"’
Upvotes: 0
Views: 708
Reputation: 47146
the xyValyes method extracted values from a raster using points (xy coordinates). This function has been replaced with extract
. So instead of
library(raster)
xyValues(x, xy, ...)
You should be able to do
extract(x, xy, ...)
Upvotes: 1
Reputation: 1053
Couple of ways you can address this issue.
Do you actually need the old function to do the work, or can it be done with a newer generation function? I'm not really clear what you're trying to do, so I can't suggest a better function.
Based on my assumptions through what you're doing and the help documentation for xyValues()
this is my guess.
First you need to use approxNA()
(requires stack) this performs the interpolation as it would in xyValues()
to fill in NA
s in your raster. Then you need to turn it into a data.frame
or a vector
of values. This can be done with either as.data.frame()
or getValues()
.
If you do not have NAs you need to fill, you can just pull the values with getValues()
or as.data.frame()
dat.r <- raster(matrix(nrow = 100,ncol = 100,sample(x = 1:1000,size = 10000,replace = T)))
dat.vector <- getValues(dat.r)
dat.dataframe <- as.data.frame(dat.r)
If you do have NAs - I found a suggestion here: Fill in gaps (e.g. not single cells) of NA values in raster using a neighborhood analysis
## Add in some NAs
dat.r[sample(1:10000,1000)] <- NA
fill.na <- function(x) {
center = 0.5 + (width*width/2)
if( is.na(x)[center] ) {
return( round(mean(x, na.rm=TRUE),0) )
} else {
return( round(x[center],0) )
}
}
width = 9
r2 <- focal(dat.r, w = matrix(1,width,width), fun = fill.na,
pad = TRUE, na.rm = FALSE)
dat.vector <- getValues(r2)
dat.dataframe<- as.data.frame(r2)
You can just source everything you need from the unpacked tar.
source("~/raster_1.5-8/raster/R/xyValues.R")
source("~/raster_1.5-8/raster/R/xyValuesBuffer.R")
source("~/raster_1.5-8/raster/R/bilinearValue.R")
source("~/raster_1.5-8/raster/R/readCells.R")
~ is the directory to where you have unpacked raster_1.5-8 A quick noted on why there are 4 scripts and not just the 1 you are after. Any function with a leading . is a hidden function that gets loaded with the package but is not explictly executable. As you are not instantiating the package, you need these helper functions.
You can attempt to install and older version of the package following the instructions here. https://support.rstudio.com/hc/en-us/articles/219949047-Installing-older-versions-of-packages The code you would need is:
require(devtools)
install_version("raster", version = "1.5-8", repos = "http://cran.us.r-project.org/")
This may result in problems down the line if you are trying to use current generation functions, so I would not recommend this method
Upvotes: 1