问题
I have a function similar to this one:
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)
I want to obtain a new vector that contains the elements of v
where isGoodNumber(v) == TRUE
How do I do this ?
Tried v [ isGoodNumber(v) == TRUE ]
but it doesn't work :-)
Thanks !!
回答1:
You'll need to Vectorize the function to call it on a vector:
isGoodNumber = Vectorize(isGoodNumber)
v[isGoodNumber(v)]
回答2:
There is a function named "Filter" that will do exactly what you want:
Filter( isGoodNumber, v)
#[1] 5 5 5 5
There would be the option of making a function that was vectorized, either by by the use of the Vectorize
function (already illustrated) or writing it with ifelse
(also mentioned) and there would be the option of a function that was "Filter"-like
isGoodNumber3 <- function(X)
{ X[ ifelse(X==5, TRUE,FALSE)]
}
isGoodNumber3(v)
#[1] 5 5 5 5
回答3:
I think here is the easiest method
> v<-c(1,2,3,4,5,5,5,5)
> v[v==5]
[1] 5 5 5 5
回答4:
Use 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
回答5:
You should get into the habit of writing vectorised functions where possible. For example, if you're writing a function f(x)
, make sure it works when x
is a vector, not just a single number. Don't rely on Vectorize
to do this for you, because it will be slow for very large vectors.
A useful technique is to replace if ... then ... else
with ifelse
. For example:
isGoodNumber <- function(X)
{
ifelse(X==5, TRUE, FALSE)
}
v<-c(1,2,3,4,5,5,5,5)
v [ isGoodNumber(v) == TRUE ]
In this particular case you can of course streamline things:
isGoodNumber <- function(X) return(X==5)
or even just
v[v==5]
but the ifelse
technique will be useful more generally.
来源:https://stackoverflow.com/questions/9265553/r-filter-a-vector-using-a-function