Ответ 1
Вам понадобится Vectorize функция, чтобы вызвать ее по вектору:
isGoodNumber = Vectorize(isGoodNumber)
v[isGoodNumber(v)]
У меня есть функция, подобная этой:
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 ]
, но он не работает: -)
Спасибо!
Вам понадобится Vectorize функция, чтобы вызвать ее по вектору:
isGoodNumber = Vectorize(isGoodNumber)
v[isGoodNumber(v)]
Существует функция с именем "Фильтр", которая будет делать именно то, что вы хотите:
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
Я думаю, что это самый простой способ
> v<-c(1,2,3,4,5,5,5,5)
> v[v==5]
[1] 5 5 5 5
Используйте 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
Вы должны привыкнуть писать векторизованные функции, где это возможно. Например, если вы пишете функцию 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
будет полезен в более общем плане.