【问题标题】:conflict between overlay and ifelse functions in r-rasterr-raster中overlay和ifelse函数之间的冲突
【发布时间】:2016-07-05 22:28:25
【问题描述】:

我在运行代码时发现在光栅包中的 overlay 内使用 ifelse 函数时出现了奇怪的行为。简而言之,如果每个栅格的前5个值是NA,函数就会报错。 为什么会这样? 下面是一个简短的代码,它模仿了我使用 R 3.2.3 和光栅版本 2.5-2 发现的问题,以及我正在考虑同时使用的一些临时解决方案。

谢谢

卡洛斯·阿尔贝罗

library(raster)
cob1d <- raster(matrix(1,nr=6,nc=6))
cob1 <- cob1d; cob2 <- cob1d; cob3 <- cob1d
overlay(cob1, cob2, cob3, fun=function(x1, x2, x3)  ifelse(x1 > 0, x1 + x2 + x3,  x3))

# class       : RasterLayer 
# dimensions  : 6, 6, 36  (nrow, ncol, ncell)
# resolution  : 0.1666667, 0.1666667  (x, y)
# extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
# coord. ref. : NA 
# data source : in memory
# names       : layer 
# values      : 3, 3  (min, max)


# Changing the first 5 values...

cob1[1:5] <- NA; cob2[1:5] <- NA; cob3[1:5] <- NA
overlay(cob1, cob2, cob3, fun=function(x1, x2, x3)  (x1 + x2 + x3))

给出了相同的结果...

# but if I use `ifelse`, there is a problem:

overlay(cob1, cob2, cob3, fun=function(x1, x2, x3)  ifelse(x1 > 0, x1 + x2 + x3,  x3))
# Error in ifelse(x1, x1 + x2 + x3, x3) : 
#  argument "x2" is missing, with no default 

# Another way to solve it is adding a useless extra variable without `NA`.

cob4 <- cob1d
overlay(cob1, cob2, cob3, cob4, fun=function(x1, x2, x3, x4)  ifelse(x1 > 0, x1 + x2 + x3,  x3))
# same result as before...
# class       : RasterLayer 
# dimensions  : 6, 6, 36  (nrow, ncol, ncell)
# resolution  : 0.1666667, 0.1666667  (x, y)
# extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
# coord. ref. : NA 
# data source : in memory
# names       : layer 
# values      : 3, 3  (min, max)

# or just avoiding the use of the `ifelse` function...

overlay(cob1, cob2, cob3, cob4, fun=function(x1, x2, x3, x4)  (x1 > 0) * (x1 + x2 + x3) + (x1 <= 0)*x3)

【问题讨论】:

  • 我遇到了同样的错误。不知道为什么...
  • 您是否也在使用ifelse 函数?你能复制你正在使用的函数或它的简化版本吗?
  • 我刚刚试用了您的代码并收到了相同的错误消息。但是我真的不明白使用 ifelse 函数的这种奇怪行为

标签: r r-raster


【解决方案1】:

这是一个有趣的案例。 overlay 使用前 5 个单元格来确定如何处理数据(通过apply 或通过do.call)。第一个测试是看apply能不能用。如果所有值都是NA,则使用的函数可以通过apply 运行

f <- function(x1, x2, x3)  ifelse(x1 > 0, x1 + x2 + x3,  x3)
m <- matrix(NA, 5, 3)
apply(m, 1, f)

根据该测试,apply 用于所有单元格。但是,当并非所有值都是 NA 时,apply 使用此函数会失败:

m[1] <- 1
apply(m, 1, f)

这失败了,因为只有一个第一个参数 x(而不是 f 要求的三个参数)。

相反 的情况很常见(当只提供 NA 值时函数会失败)这种情况很少见。

raster:::calc 具有参数forcefun 以避免使用apply,但这在overlay 中不可用。我已将其添加到 raster(版本 >= 2.5-4)的未来版本中,您可以这样做:

f <- function(x1, x2, x3)  ifelse(x1 > 0, x1 + x2 + x3,  x3)
overlay(cob1, cob2, cob3, fun=f, forcefun=TRUE)

无论如何,您都可以使用calc 作为解决方法:

s <- stack(cob1, cob2, cob3)
r <- calc(s, fun=function(x)  ifelse(x[1] > 0, x[1] + x[2] + x[3],  x[3]))

或另一种选择,基于您的替代功能:

r <- (cob1 > 0) * (cob1 + cob2 + cob3) + (cob1 <= 0)*cob3 

【讨论】:

    【解决方案2】:

    也许你必须在你的函数中使用每个“x”的条件,例如

    overlay(cob1, cob2, cob3, fun=function(x1, x2, x3)  ifelse(x1 > 0 & x2 >0 & x3 >0 , x1 + x2 + x3,  x3))
    

    不只是x1的条件(x1&gt;0

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-11
      • 2018-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多