2012-01-09 67 views
5

Tôi muốn xác định hàm piecewise sử dụng R, tuy nhiên, mã R của tôi bị sai. Bất kỳ đề nghị được chào đón.Cách xác định hàm piecewise trong 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

Có thể đáng làm rõ rằng ví dụ này là một hàm bước, một lớp đặc biệt của các chức năng tham chiếu. Đối với các hàm bước, 'stepfun' (được đề cập bởi @KenWIlliams) và' approxfun' đều hoạt động tốt. 'approxfun' cũng chứa các hàm số piecewise-linear (nhưng không chứa hàm piecewise chung). – dzeltzer

Trả lời

12

Hoặc bạn có thể sử dụng 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

Có lẽ nếu bạn chia các điều kiện

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

EDIT: Điều này có vẻ không phải là tất cả, đây là một cách tiếp cận khác nhau:

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

Cảm ơn bạn đã trả lời. Tôi sẽ có một thử. –

+0

Cách tiếp cận của bạn không hoạt động. Cảm ơn rất nhiều. –

+1

Hãy cẩn thận với các bit đó '&'. Không có vấn đề gì trong trường hợp này, nhưng tốt hơn nên gắn bó với '&&', và tương tự '||' thay vì '|'. – fotNelton

15

Hãy thử điều này:

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

Rất đẹp.Với kinh nghiệm của Gabor, tôi đặt cược điều này chạy nhanh hơn (đối với số lượng lớn 'phân đoạn') so với cách tiếp cận "chuyển đổi" của tôi. –

1

Trừ khi bạn đã thay đổi điểm cắt, tôi muốn sử dụng switch. Dưới đây là ví dụ với các giá trị được cắt đơn giản.

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

Vòng lặp qua x.

+0

phương pháp rất tốt. cảm ơn. –

2

Còn một tùy chọn khác, lần này sử dụng 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

cảm ơn. nó rất hữu ích. –

10

Tôi hơi muộn với bữa tiệc, nhưng tôi không thể cưỡng lại việc đăng thêm một vài cách để làm điều này. Cả hai đều tận dụng khả năng của R để làm việc với các khoảng thời gian trên dòng thực.

Nếu bạn xác định điểm cắt của bạn và các giá trị chức năng trong các vectơ cutsvals như vậy:

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) 

Sau đó, bạn có thể sử dụng findInterval để hiệu quả tìm kiếm các giá trị của x trong cutpoints của bạn:

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

Nếu chức năng này cần thiết để làm những thứ huyền ảo hơn là chỉ tìm kiếm một giá trị không đổi, bạn có thể đặt các biểu thức hoặc chức năng hoặc bất cứ điều gì bạn muốn trong vals, có thể là usi ng a list nếu bạn muốn.

Ngoài ra, kể từ khi chức năng này là một chức năng bước, bạn có thể sử dụng stepfun:

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

Sau đó, bạn cũng nhận được để sử dụng các phương pháp âm mưu tốt đẹp của stepfun quá.

Các vấn đề liên quan