Подтвердить что ты не робот

R - фильтровать вектор, используя функцию

У меня есть функция, подобная этой:

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)

Я хочу получить новый вектор, содержащий элементы v, где isGoodNumber(v) == TRUE

Как это сделать?

Пробовал v [ isGoodNumber(v) == TRUE ], но он не работает: -)

Спасибо!

4b9b3361

Ответ 1

Вам понадобится Vectorize функция, чтобы вызвать ее по вектору:

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

Ответ 2

Существует функция с именем "Фильтр", которая будет делать именно то, что вы хотите:

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

Можно было бы сделать функцию, которая была векторизована, либо с помощью функции Vectorize (уже проиллюстрированной), либо написав ее с помощью ifelse (также упомянутой), и была бы возможность функция, которая была "Filter" -like

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

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

Ответ 3

Я думаю, что это самый простой способ

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

Ответ 4

Используйте 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

Вы должны привыкнуть писать векторизованные функции, где это возможно. Например, если вы пишете функцию f(x), убедитесь, что она работает, когда x - это вектор, а не только один номер. Не полагайтесь на Vectorize, чтобы сделать это для вас, потому что он будет медленным для очень больших векторов.

Полезным методом является замена if ... then ... else на ifelse. Например:

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

В этом конкретном случае вы можете, конечно, упорядочить вещи:

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

или даже просто

v[v==5]

но метод ifelse будет полезен в более общем плане.