2009-12-03 9 views
1

le seuil inférieur. une logique similaire décrirait un thermostat normal dans un four domestique. évidemment je veux que ça marche sur les vecteurs, c'est tout l'intérêt!double seuil (on/off) avec

donc si je trouve les données

S <- c(50, 100, 150, 180, 210, 200, 190, 182, 175, 185, 195, 205) 

ma fonction indique si la température du four est bien. l'inverse logique de "allumer le four".

R> thresholdOnOff(S, 180, 200) 
[1] FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE FALSE FALSE FALSE TRUE 

la question est un style de programmation: j'ai d'abord essayé d'écrire avec une fonction « appliquer » en elle, mais je l'avais oublié de prendre en compte les environnements ... j'ai donc écrit une version de travail avec un « pour «boucle - qui ne me plaisait pas, alors rappeler à propos de l'environnement et je ne suis pas sûr au sujet des deux versions:

thresholdOnOff <- local({ 
    ## following the R inferno 
    f <- function(series, lower, upper, initialValue=FALSE) { 
    status <<- initialValue 

    switchOnOff <- function(x) { 
     if(x > upper) 
     status <<- TRUE 
     if(x < lower) 
     status <<- FALSE 
     return(status) 
    } 

    sapply(series, switchOnOff) 
    } 
}) 


thresholdOnOff <- function(series, lower, upper, initialValue=FALSE) { 
    ## just guessing and reading from the documentation 
    status <- initialValue 

    switchOnOff <- function(x) { 
    if(x > upper) 
     assign('status', TRUE, inherits=TRUE) 
    if(x < lower) 
     assign('status', FALSE, inherits=TRUE) 
    return(status) 
    } 

    sapply(series, switchOnOff) 
} 

Répondre

1

est ici une solution efficace sans boucles:

library("zoo") 
S <- c(50, 100, 150, 180, 210, 200, 190, 182, 175, 185, 195, 205) 

thresholdOnOff <- function(x, low, high, initial.value=FALSE) { 
    require("zoo") 
    s <- rep(NA, length(x)) 
    s[1] <- initial.value 
    s[x > high] <- TRUE 
    s[x < low] <- FALSE 
    return(na.locf(s)) 
} 

thresholdOnOff(S, 180, 200) 

Alternat ivement, vous pouvez utiliser ifelse dans une ligne pour résoudre ce problème, mais ce sera beaucoup plus lent si vous avez données volumineuses:

na.locf(ifelse(S > 200, TRUE, ifelse(S < 180, FALSE, NA))) 
+0

Eh bien, vous avez raison, je n'ai pas * expliquer * ce qui devrait se passer entre les deux seuils, j'ai seulement donné la définition 'par exemple' ... comme dans un ménage physique "logique du four" dans son état précédent. (S> 200 ne calcule pas le vecteur logique dont j'ai besoin). mais votre réponse me rappelle la fonction na.locf et [cette autre question] (http://stackoverflow.com/questions/1782704 "propagation de données dans un vecteur"). – mariotomo

1

bâton avec une boucle. Si les valeurs ne sont pas indépendantes, il n'y a aucun avantage à utiliser apply.

Sauf si vous avez une très bonne raison, vous devriez éviter les effets secondaires dans les fonctions.