2012-01-09 16 views
5

Voglio definire una funzione a tratti usando R, tuttavia, il mio codice R va errato. Qualsiasi suggerimento è benvenuto.Come definire una funzione a tratti in R

x<-seq(-5, 5, by=0.01) 
    for (x in -5:5){ 
    if (-0.326 < x < 0.652) fx<- 0.632 
    else if (-1.793<x<-1.304) fx<- 0.454 
    else if (1.630<x<2.119) fx<-0.227 
    else fx<- 0 } 
+0

Potrebbe essere utile chiarire che questo esempio è una funzione di passaggio, una classe speciale di funzioni a tratti. Per le funzioni di passaggio, 'stepfun' (citato da @KenWIlliams) e' approxfun' funzionano entrambi bene. 'approxfun' supporta anche le funzioni lineari (ma non le funzioni a tratti in generale). – dzeltzer

risposta

12

Oppure si potrebbe usare ifelse.

fx <- ifelse(x > -0.326 & x <0.625, 0.632, 
    ifelse(x > -1.793 & x < -1.304, 0.454, 
    ifelse(x > 1.630 & x < 2.119, 0.227, 0))) 
2

Forse se si dividono le condizioni

if((-1.793<x) & (x < 0.652)) ... 

EDIT: Questo sembra non essere tutto, ecco un approccio diverso:

x<-seq(-5, 5, by=0.01) 
fx <- function(x) { 
    res <- rep(0, length(x)) 
    res[(-0.326 < x) & (x < 0.652)] <- 0.632 
    res[(-1.793<x) & (x < (-1.304))] <- 0.454 
    res[(1.630<x) & (x <2.119)] <- 0.227 
    return(res) 
} 
fx(x) 
+0

Grazie per la risposta. Ci proverò. –

+0

Il tuo approccio funziona. Grazie mille. –

+1

Prestare attenzione a quelli bit per bit '&'. In questo caso non è un problema, ma è meglio attenersi a '&&', e allo stesso modo '||' invece di '|'. – fotNelton

15

Prova questa:

x <- seq(-5, 5, 0.01) 
fx <- (x > -0.326 & x <0.625) * 0.632 + 
     (x > -1.793 & x < -1.304) * 0.454 + 
     (x > 1.630 & x < 2.119) * 0.227 
plot(x, fx) 
+0

Bello.Considerata l'esperienza di Gabor, scommetto che questo funziona più velocemente (per un gran numero di "segmenti") rispetto al mio approccio "switch". –

1

meno che non si hanno diversi punti di taglio, userei switch. Ecco un esempio con valori di taglio semplificati.

xcuts<-1:10 #the values at which you change fx assignment 
xx<- seq(1.5,10,5, by =10) #vector of fx values to be selected 
switch(max(which(x>xcuts)), 
1= fx<-xx[1], 
2= fx<-xx[2], 
..."et cetera"... 
) 

Ciclo su x.

+0

ottimo metodo. grazie. –

2

Un'altra opzione, questa volta utilizzando cut.

regions <- c(-Inf, -1.793, -1.304, -0.326, 0.652, 1.63, 2.119, Inf) 
group <- cut(x, regions) 
f_values <- c(0, 0.454, 0, 0.632, 0, 0.227, 0) 
(fx <- f_values[group]) 
+0

grazie. è molto utile. –

10

Sono un po 'in ritardo alla festa, ma non ho potuto resistere la pubblicazione di un altro paio di modi per farlo. Entrambi sfruttano le capacità R per lavorare con intervalli sulla linea reale.

Se si definiscono i punti di taglio e valori della funzione nei vettori cuts e vals in questo modo:

cuts <- c(-Inf, -1.793, -1.304, -0.326, 0.625, 1.630, 2.119) 
vals <- c( 0, 0.454,  0, 0.632,  0, 0.227,  0) 

Quindi è possibile utilizzare findInterval per cercare in modo efficiente i valori di x nei vostri punti di divisione:

fx <- vals[findInterval(x, c(-Inf, cuts))] 

Se questa funzione è necessaria per creare cose più divertenti di un semplice valore costante, è possibile inserire espressioni, funzioni o qualsiasi cosa in vals, eventualmente utilizzare ng a list se vuoi.

In alternativa, dal momento che questa funzione è una funzione di passo, è possibile utilizzare stepfun:

f <- stepfun(cuts[-1], vals) 
fx <- f(x) 

Poi è anche arrivare a utilizzare i metodi di plottaggio belle di stepfun troppo.

Problemi correlati