R - 使用函数过滤矢量

Mad*_*Seb 39 r function vector

我有一个类似于这个的功能:

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)
Run Code Online (Sandbox Code Playgroud)

我想获得一个包含vwhere 的元素的新向量isGoodNumber(v) == TRUE

我该怎么做呢 ?

尝试v [ isGoodNumber(v) == TRUE ]但它不起作用:-)

谢谢 !!

42-*_*42- 54

有一个名为" Filter " 的函数可以完全按照您的要求执行:

Filter( isGoodNumber, v)
#[1] 5 5 5 5
Run Code Online (Sandbox Code Playgroud)

可以选择通过使用Vectorize函数(已经说明)或用ifelse(也提到过)编写函数来制作一个矢量化的函数,并且可以选择"过滤器"类似的函数

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

 isGoodNumber3(v)
#[1] 5 5 5 5
Run Code Online (Sandbox Code Playgroud)

  • 这是唯一不需要重复"v"的答案,如果`v`是计算表达式,这是一件好事**. (4认同)

xjz*_*hou 29

我认为这是最简单的方法

> v<-c(1,2,3,4,5,5,5,5)
> v[v==5]
[1] 5 5 5 5
Run Code Online (Sandbox Code Playgroud)


Dav*_*son 24

你需要对函数进行矢量化以在向量上调用它:

isGoodNumber = Vectorize(isGoodNumber)
v[isGoodNumber(v)]
Run Code Online (Sandbox Code Playgroud)


Ale*_*lds 7

使用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
Run Code Online (Sandbox Code Playgroud)


Ale*_*ysz 5

您应该养成尽可能编写矢量化函数的习惯。例如,如果您正在编写函数f(x),请确保它在x是向量时有效,而不仅仅是单个数字。不要依赖于Vectorize为您执行此操作,因为对于非常大的向量来说它会很慢。

一个有用的技术是,以取代if ... then ... elseifelse。例如:

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

在这种特殊情况下,您当然可以简化事情:

isGoodNumber <- function(X) return(X==5)
Run Code Online (Sandbox Code Playgroud)

甚至只是

v[v==5]
Run Code Online (Sandbox Code Playgroud)

但该ifelse技术将更普遍地有用。