2012-02-13 36 views
34

Tôi có một chức năng tương tự với trang này:R - Lọc một vector sử dụng một hàm

isGoodNumber <- function(X) 
{ 
if (X==5) return(TRUE) else return(FALSE) 
} 

I have a vector: 
v<-c(1,2,3,4,5,5,5,5) 

Tôi muốn để có được một vector mới có chứa các yếu tố của v nơi isGoodNumber(v) == TRUE

Làm thế nào để làm điều này ?

Đã thử v [ isGoodNumber(v) == TRUE ] nhưng không hoạt động :-)

Cảm ơn !!

+0

Bạn có thể viết lại hàm này không? Hoặc là hàm được xác định và bạn không thể thay đổi nó? – Dason

+2

Tôi đoán ứng dụng thực sự của bạn phức tạp hơn ví dụ, nhưng 'v [v == 5]' sẽ thực hiện thủ thuật cho ví dụ của bạn. – Chase

+0

Xin chào @ Dason, vâng tôi có thể viết lại hàm :-) – MadSeb

Trả lời

20

Bạn sẽ cần phải Vectorize chức năng để gọi nó trên một vector:

isGoodNumber = Vectorize(isGoodNumber) 
v[isGoodNumber(v)] 
+0

có, tính năng này hoạt động!cảm ơn ! – MadSeb

7

Sử dụng mapply():

> v <- c(1,2,3,4,5,5,5,5) 
> newV <- mapply(function(X) { if (X==5) return(TRUE) else return(FALSE) }, v) 
> newV 
[1] FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE 
> v[newV == TRUE] 
[1] 5 5 5 5 
43

Có một hàm có tên "Filter" mà sẽ thực hiện chính xác những gì bạn muốn:

Filter(isGoodNumber, v) 
#[1] 5 5 5 5 

Sẽ có optio n tạo một hàm được vector hóa, hoặc bằng cách sử dụng hàm Vectorize (đã được minh họa) hoặc viết nó với ifelse (cũng được đề cập) và sẽ có tùy chọn của hàm "Lọc" giống như

isGoodNumber3 <- function(X) 
    { X[ ifelse(X==5, TRUE,FALSE)] 
    } 

isGoodNumber3(v) 
#[1] 5 5 5 5 
+2

Đây là câu trả lời duy nhất không yêu cầu lặp lại 'v', đó là một điều tốt ** nếu' v' là biểu thức được tính toán. – krlmlr

20

tôi nghĩ rằng đây là phương pháp đơn giản nhất

> v<-c(1,2,3,4,5,5,5,5) 
> v[v==5] 
[1] 5 5 5 5 
4

Bạn sẽ nhận được vào các thói quen viết vectorised chức năng nếu có thể. Ví dụ, nếu bạn đang viết một hàm f(x), hãy đảm bảo nó hoạt động khi x là một véc tơ, không chỉ là một số duy nhất. Đừng dựa vào Vectorize để làm điều này cho bạn, bởi vì nó sẽ làm chậm các vectơ rất lớn.

Một kỹ thuật hữu ích là thay thế if ... then ... else bằng ifelse. Ví dụ:

isGoodNumber <- function(X) 
{ 
    ifelse(X==5, TRUE, FALSE) 
} 
v<-c(1,2,3,4,5,5,5,5) 
v [ isGoodNumber(v) == TRUE ] 

Trong trường hợp này bạn có thể sắp xếp tất nhiên điều:

isGoodNumber <- function(X) return(X==5) 

hoặc thậm chí chỉ

v[v==5] 

nhưng kỹ thuật ifelse sẽ hữu ích tổng quát hơn.

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