2012-12-13 14 views

risposta

17

Rcpp ha clamp per questo:

cppFunction('NumericVector rcpp_clip(NumericVector x, double a, double b){ 
    return clamp(a, x, b) ; 
}') 

Ecco un breve riferimento che mostra come si svolge contro altri metodi discussi:

pmin_pmax_clip <- function(x, a, b) pmax(a, pmin(x, b)) 
ifelse_clip <- function(x, a, b) { 
    ifelse(x <= a, a, ifelse(x >= b, b, x)) 
} 
operations_clip <- function(x, a, b) { 
    a + (x-a > 0)*(x-a) - (x-b > 0)*(x-b) 
} 
x <- rnorm(10000) 
require(microbenchmark) 

microbenchmark( 
    pmin_pmax_clip(x, -2, 2), 
    rcpp_clip(x, -2, 2), 
    ifelse_clip(x, -2, 2), 
    operations_clip(x, -2, 2) 
) 
# Unit: microseconds 
#      expr  min  lq median  uq  max 
# 1  ifelse_clip(x, -2, 2) 2809.211 3812.7350 3911.461 4481.0790 43244.543 
# 2 operations_clip(x, -2, 2) 228.282 248.2500 266.605 1120.8855 40703.937 
# 3 pmin_pmax_clip(x, -2, 2) 260.630 284.0985 308.426 336.9280 1353.721 
# 4  rcpp_clip(x, -2, 2) 65.413 70.7120 84.568 92.2875 1097.039  
+0

Questi tempi sono piuttosto rock. –

+0

Basta incollare le righe per il codice della pinza in una sessione della console ovviamente non è quello che intendevi fare noi vergini Rcpp. –

+0

Quasi. Vedi il mio uso di 'cppFunction' nella mia modifica. (ma è necessario l'attuale versione di sviluppo di 'Rcpp' perché' clamp' è stato corretto dall'ultima versione). –

7

Ecco una funzione che funziona per entrambi i vettori e matrici.

myClip <- function(x, a, b) { 
    ifelse(x <= a, a, ifelse(x >= b, b, x)) 
} 

myClip(x = 0:10, a = 3,b = 7) 
# [1] 3 3 3 3 4 5 6 7 7 7 7 

myClip(x = matrix(1:12/10, ncol=4), a=.2, b=0.7) 
# myClip(x = matrix(1:12/10, ncol=4), a=.2, b=0.7) 
#  [,1] [,2] [,3] [,4] 
# [1,] 0.2 0.4 0.7 0.7 
# [2,] 0.2 0.5 0.7 0.7 
# [3,] 0.3 0.6 0.7 0.7 

Ed ecco un altro:

myClip2 <- function(x, a, b) { 
    a + (x-a > 0)*(x-a) - (x-b > 0)*(x-b) 
} 

myClip2(-10:10, 0, 4) 
# [1] 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 4 4 4 4 4 4 
+0

Grande !! Grazie mille!! La mia funzione era più lenta, ma questo funziona abbastanza velocemente! –

+1

Questo dovrebbe essere nella libreria di base di R! – smci

13

Ecco un metodo con nidificato pmin e pmax impostare i limiti:

fenced.var <- pmax(LB, pmin(var, UB)) 

Sarà difficile trovare un metodo che è più veloce. Avvolto in una funzione che imposta automaticamente una serie di 3 e 7:

fence <- function(vec, UB=7, LB=3) pmax(LB, pmin(vec, UB)) 

> fence(1:10) 
[1] 3 3 3 4 5 6 7 7 7 7 
+0

dolce .......... –

+0

Molto elegante - è fantastico! –

+0

Io uso questo molto. Ho un set di dati di grandi dimensioni che ha diverse variabili che non sono plausibilmente reali al di sotto di 0 e che dovrebbero essere vincolate anche alla fascia alta. Il vero trucco è ricordarsi di impostare il massimo con 'pmin' e impostare il minimo con' pmax'. –

1

Credo che sarebbe clamp() dal pacchetto raster.

library(raster) 
clamp(x, lower=-Inf, upper=Inf, ...) 
Problemi correlati