如何将R代码从旧程序包的函数转换为当前版本的R中的有效函数

问题描述 投票:0回答:1

我通常使用Matlab,并且在谈到R时只是一个业余爱好者。我一直在尝试使用2011年以来的其他代码,它正在调用一个名为'xyvalues'的函数。我发现这曾经是Raster软件包(版本1.5.8)中的功能,但不再出现在当前版本中。旧的栅格包与R的较新版本不兼容。我曾尝试将R降级,但这会导致其他问题。

我已经下载了tar.gz文件并提取了xyValues函数的代码。我试图将其粘贴到我的较新版本的Raster软件包中,但是毫不奇怪,它没有起作用。我有一种简单的方法可以将此函数的代码转换为可以保存然后使用的实际函数(就像我自己编写该函数一样)吗?我可以在matlab中轻松完成此操作,但是似乎在R中编写函数的过程有些不同,而且我真的不知道从哪里开始?我在此站点上看到了该问题的一些变体,但我想知道R的新用户(例如我)是否有能力执行我的建议。也许只有您对R有很多知识,才有可能。这是我提取的代码:

# 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.')
  }
}

作为对该问题的后续,起初,当我想查看此函数是否在我的栅格数据包中时,我尝试键入help(xyValues),但没有任何反应(因为它不存在)。但是,当我针对包中确实存在的功能尝试这种操作时,它们也不会出现。这是否意味着我的栅格数据包未正确加载?

我正在其中使用该函数的代码段是:

elevgrid <- xyValues(elev,cbind(xygrid[,2],xygrid[,1]))

其中elev是大小为920x1000的形式类栅格图层,xygrid是4800 obs,包含2个变量(x y坐标)

我尝试使用:

> source("C:/Users/Documents/raster/R/xyValues.R")

但是我遇到了所有这些错误:

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” 
r function r-raster
1个回答
1
投票

您可以通过多种方式解决此问题。

最重要的是:

您实际上是否需要旧功能来完成工作,还是可以使用较新的一代功能来完成?我不清楚您要做什么,所以我不能建议您使用更好的功能。

基于我所做的假设以及xyValues()的帮助文档,这是我的猜测。首先,您需要使用approxNA()需要堆栈)来执行插值,就像在xyValues()中填充栅格中的NA一样。然后,您需要将其转换为data.framevector值。可以用as.data.frame()getValues()完成。如果您没有NA,则需要填写,只需使用getValues()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)

如果您有NA的话-我在这里找到了一个建议: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)

第二:

您可以从解压缩的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")

〜是解压缩raster_1.5-8的目录快速说明为什么有4个脚本,而不仅仅是您需要的1个。任何带前导功能。是一个隐藏函数,已随软件包一起加载,但不能明确执行。由于您没有实例化软件包,因此需要这些帮助函数。

第三不推荐

您可以按照此处的说明尝试安装和安装较旧版本的软件包。https://support.rstudio.com/hc/en-us/articles/219949047-Installing-older-versions-of-packages您需要的代码是:

require(devtools)
install_version("raster", version = "1.5-8", repos = "http://cran.us.r-project.org/")

如果您尝试使用当前生成的函数,这可能会导致问题,所以我不建议您使用此方法

© www.soinside.com 2019 - 2024. All rights reserved.