Reputation: 13
I am manipulating raster data in R with the rgdal
and raster
packages. I want to get rid of all infinite, no values, negative values and replace them with zero:
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)
Then the ndii_noNA
have only a value of 0. I tried if else statement but it raises an error in
.calcTest(x[1:5], fun, na.rm, forcefun, forceapply).
Is there any way to solve this?
Upvotes: 1
Views: 176
Reputation: 674
Edit: ifelse() is cleaner but the @cgmil's answer is indeed faster.
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
Upvotes: 0
Reputation: 440
You are very close, but have made two errors:
which()
in the index of x
, rather than just the truth statement. Otherwise, you will index either x[TRUE]
or x[FALSE]
, which is not what you want. which()
will return the indices of all "bad" elements in your vector.<-
, the local copy of x
will be changed, not the one that was passed. If you want to change x
in place, you need to use <<-
. That said, you would be wise to stick to R's functional paradigm, in which you would make the change to the local copy, then return it with return(x)
, rather than change in place.Here is the function you want:
# 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)
}
Upvotes: 1