如何编写多个 if 语句 R
How to write multiple if statement R
我正在使用 rgdal
和 raster
包在 R 中处理栅格数据。我想摆脱所有无限,无值,负值并将它们替换为零:
NoNA <- function (x) {
x[is.infinite(x) | is.na(x) | is.nan(x) | is.null(x) | is.na(x < 0)] <- 0
}
ndii_noNA <- calc(ndii, NoNA)
然后 ndii_noNA
的值只有 0。我尝试了 if else 语句,但它在
中引发了错误
.calcTest(x[1:5], fun, na.rm, forcefun, forceapply).
有什么办法可以解决吗?
你很接近,但是犯了两个错误:
- 你需要在
x
的索引中使用which()
,而不仅仅是真值语句。否则,您将索引 x[TRUE]
或 x[FALSE]
,这不是您想要的。 which()
将 return 向量中所有 "bad" 元素的索引。
- 当你用
<-
赋值时,x
的本地副本将被改变,而不是被传递的那个。如果你想原地改变x
,你需要使用<<-
。也就是说,您最好坚持 R 的功能范例,在该范例中,您将对本地副本进行更改,然后 return 使用 return(x)
,而不是就地更改。
这是你想要的功能:
# The "change in place" method (may be considered bad style)
NoNA <- function(x) {
x[which(is.infinite(x) | is.na(x) | is.nan(x) | is.null(x) | is.na(x < 0))] <<- 0
}
# The functional way (recommended)
NoNA <- function(x) {
x[which(is.infinite(x) | is.na(x) | is.nan(x) | is.null(x) | is.na(x < 0))] <- 0
return(x)
}
编辑:ifelse() 更简洁,但@cgmil 的回答确实更快。
x = rep(c(Inf, -Inf, NULL, NaN, NA, 1), 250e3)
no_na = function(x){
ifelse(
is.infinite(x) | is.na(x) | is.nan(x) | is.null(x) | is.na(x < 0), 0, x
)
}
NoNA <- function(x) {
x[which(is.infinite(x) | is.na(x) | is.nan(x) | is.null(x) | is.na(x < 0))] <- 0
return(x)
}
microbenchmark(
no_na(x), NoNA(x),
times = 50
)
# Unit: milliseconds
# expr min lq mean median uq max neval
# no_na(x) 380.9375 399.7520 416.7729 424.5490 429.6005 451.0534 50
# NoNA(x) 242.8555 249.0034 255.8857 251.3694 254.8176 285.1451 50
我正在使用 rgdal
和 raster
包在 R 中处理栅格数据。我想摆脱所有无限,无值,负值并将它们替换为零:
NoNA <- function (x) {
x[is.infinite(x) | is.na(x) | is.nan(x) | is.null(x) | is.na(x < 0)] <- 0
}
ndii_noNA <- calc(ndii, NoNA)
然后 ndii_noNA
的值只有 0。我尝试了 if else 语句,但它在
.calcTest(x[1:5], fun, na.rm, forcefun, forceapply).
有什么办法可以解决吗?
你很接近,但是犯了两个错误:
- 你需要在
x
的索引中使用which()
,而不仅仅是真值语句。否则,您将索引x[TRUE]
或x[FALSE]
,这不是您想要的。which()
将 return 向量中所有 "bad" 元素的索引。 - 当你用
<-
赋值时,x
的本地副本将被改变,而不是被传递的那个。如果你想原地改变x
,你需要使用<<-
。也就是说,您最好坚持 R 的功能范例,在该范例中,您将对本地副本进行更改,然后 return 使用return(x)
,而不是就地更改。
这是你想要的功能:
# The "change in place" method (may be considered bad style)
NoNA <- function(x) {
x[which(is.infinite(x) | is.na(x) | is.nan(x) | is.null(x) | is.na(x < 0))] <<- 0
}
# The functional way (recommended)
NoNA <- function(x) {
x[which(is.infinite(x) | is.na(x) | is.nan(x) | is.null(x) | is.na(x < 0))] <- 0
return(x)
}
编辑:ifelse() 更简洁,但@cgmil 的回答确实更快。
x = rep(c(Inf, -Inf, NULL, NaN, NA, 1), 250e3)
no_na = function(x){
ifelse(
is.infinite(x) | is.na(x) | is.nan(x) | is.null(x) | is.na(x < 0), 0, x
)
}
NoNA <- function(x) {
x[which(is.infinite(x) | is.na(x) | is.nan(x) | is.null(x) | is.na(x < 0))] <- 0
return(x)
}
microbenchmark(
no_na(x), NoNA(x),
times = 50
)
# Unit: milliseconds
# expr min lq mean median uq max neval
# no_na(x) 380.9375 399.7520 416.7729 424.5490 429.6005 451.0534 50
# NoNA(x) 242.8555 249.0034 255.8857 251.3694 254.8176 285.1451 50