r-raster中overlay和ifelse函数之间的冲突

Car*_*rto 5 r r-raster

我正在运行一个代码,并在光栅包中使用一个ifelse函数时发现了一个奇怪的行为overlay.简而言之,如果每个栅格的前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))
Run Code Online (Sandbox Code Playgroud)

给出了相同的结果......

# 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)
Run Code Online (Sandbox Code Playgroud)

Rob*_*ans 5

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

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

基于该测试,apply用于所有细胞.但是,apply当并非所有值都是NA:

m[1] <- 1
apply(m, 1, f)
Run Code Online (Sandbox Code Playgroud)

这失败了,因为只有一个第一个参数x(不需要三个参数f).

虽然相反的情况很常见(只NA提供值时失败的功能),但这种情况很少见.

raster:::calcforcefun避免使用的论据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)
Run Code Online (Sandbox Code Playgroud)

无论如何,您可以将其calc用作解决方法:

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

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

r <- (cob1 > 0) * (cob1 + cob2 + cob3) + (cob1 <= 0)*cob3 
Run Code Online (Sandbox Code Playgroud)