2016-05-04 11 views
1

Ich manipuliere Raster-Daten in R mit den rgdal und raster Pakete. Ich will, um loszuwerden, alle unendlich, ohne Werte, negative Werte und ersetzen sie durch Null:Wie schreibe ich mehrere if-Anweisung 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) 

Dann wird der ndii_noNA haben nur einen Wert von 0 ich, wenn else-Anweisung versucht, aber es löst einen Fehler in

.calcTest(x[1:5], fun, na.rm, forcefun, forceapply). 

Gibt es eine Möglichkeit, dies zu lösen?

+3

Sie brauchen '{x [stuff] <- 0; x} 'Sie geben gerade die zugewiesenen Werte zurück, nicht das Objekt' x' – rawr

+0

Sie müssen den x-Vektor nach der Manipulation zurückgeben. –

+2

und Sie könnten 'x <- c (1, NA, NaN, -2, 0, 1); x [! is.finite (x) | x <0] <- 0; x' – rawr

Antwort

1

Sie sind ganz in der Nähe, haben aber zwei Fehler gemacht:

  1. Sie benötigen which() im Index von x zu verwenden, anstatt nur die Wahrheit Aussage. Andernfalls indizieren Sie entweder x[TRUE] oder x[FALSE], was nicht das ist, was Sie wollen. which() wird die Indizes aller "schlechten" Elemente in Ihrem Vektor zurückgeben.
  2. Wenn Sie die Zuweisung mit <- vornehmen, wird die lokale Kopie von x geändert, nicht die, die übergeben wurde. Wenn Sie x an Ort und Stelle ändern möchten, müssen Sie <<- verwenden. Das heißt, Sie wären klug, sich an Rs funktionelles Paradigma zu halten, bei dem Sie die Änderung an der lokalen Kopie vornehmen und sie dann mit return(x) zurückgeben, anstatt sich an Ort und Stelle zu ändern.

Hier ist die gewünschte Funktion:

# 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) 
} 
0

Edit: ifelse() ist sauberer, aber die Antwort des @ cgmil ist in der Tat schneller.

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