2012-01-09 22 views
5

Chcę zdefiniować funkcję odcinkową za pomocą R, jednak mój kod R się nie udać. Wszelkie sugestie są mile widziane.Jak zdefiniować funkcję fragmentu w 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

Warto wyjaśnić, że ten przykład jest funkcją stopniową, specjalną klasą złożonych funkcji. W przypadku funkcji krokowych, 'stepfun' (wspomniany przez @KenWIlliams) i' approxfun' oba działają dobrze. 'approxfun' również obsługuje funkcje liniowo-liniowe (ale nie ogólne funkcje w postaci kawałków). – dzeltzer

Odpowiedz

12

Albo można użyć 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

Może jeśli podzielić warunki

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

EDIT: To nie wydaje się być wszystko, tu jest inne podejście:

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

Dziękuję za odpowiedź. Spróbuję. –

+0

Twoje podejście działa. Wielkie dzięki. –

+1

Uważaj przy tych bitowych 'i'. W tym przypadku nie ma problemu, ale lepiej trzymać się '&&', a także '||' zamiast '|'. – fotNelton

15

Spróbuj tego:

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

Nice.Biorąc pod uwagę doświadczenie Gabora, założę się, że działa to szybciej (dla dużej liczby "segmentów") niż moje podejście "przełączające". –

1

Chyba że mają różne punkty odcięcia, użyję switch. Oto przykład z uproszczonymi wartościami cięcia.

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"... 
) 

Pętla powyżej x.

+0

bardzo dobra metoda. Dziękuję. –

2

Jeszcze inna opcja, tym razem za pomocą 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

dzięki. jest bardzo pomocny. –

10

Jestem trochę spóźniony na imprezę, ale nie mogłem oprzeć się dodaniu kilku innych sposobów, aby to zrobić. Oba wykorzystują możliwości R do pracy z interwałami na prawdziwej linii.

Jeśli definiować swoje punkty cięte i wartości funkcji w wektorach cuts i vals tak:

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) 

Następnie można użyć findInterval sprawnie wyszukać wartości x w swoim odcięcia:

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

Jeśli ta funkcja wymagała bardziej wyszukanych rzeczy niż tylko wyszukiwanie stałej wartości, możesz wstawiać wyrażenia lub funkcje lub cokolwiek chcesz w vals, ewentualnie usi ng a list jeśli chcesz.

Alternatywnie, ponieważ ta funkcja jest funkcją krok, można użyć stepfun:

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

Następnie można również uzyskać korzystania z ciekawych metod wykreślanie stepfun też.