Как название, я хотел бы знать, как определить векторную функцию в R.
- Это просто с помощью цикла в функции?
- Является ли этот метод эффективным?
- А какая лучшая практика?
Как название, я хотел бы знать, как определить векторную функцию в R.
Цикл на уровне R не векторизован. R-цикл будет вызывать один и тот же R-код для каждого элемента вектора, который будет неэффективным. Векторизованные функции обычно относятся к тем, которые принимают вектор и эффективно работают со всем вектором. В конечном итоге это потребует некоторых циклов, но поскольку этот цикл выполняется на низкоуровневом языке, таком как C, он может быть очень эффективным и адаптирован к конкретной задаче.
Рассмотрим эту глупую функцию, чтобы добавить попарно элементы двух векторов
sillyplus <- function(x, y) {
out <- numeric(length = length(x))
for(i in seq_along(x)) {
out[i] <- x[i] + y[i]
}
out
}
Он дает правильный результат
R> sillyplus(1:10, 1:10)
[1] 2 4 6 8 10 12 14 16 18 20
и векторизован в том смысле, что он может работать на целых векторах одновременно, но он не векторизован в том смысле, который я описываю выше, потому что он исключительно неэффективен. +
векторизован на уровне C в R, поэтому нам действительно нужно только 1:10 + 1:10
, а не явный цикл в R.
Обычным способом записи векторной функции является использование существующих R-функций, которые уже векторизованы. Если вы хотите начать с нуля, и вещь, которую вы хотите сделать с функцией, не существует как векторная функция в R (нечетная, но возможная), тогда вам нужно будет загрязнить руки и написать мужество функции в C и подготовьте небольшую обертку в R, чтобы вызвать функцию C, которую вы написали, с вектором данных, с которым вы хотите работать. Существуют способы с функциями типа Vectorize()
для подделки векторизации для R-функций, которые не являются векторизованными.
C не единственный вариант здесь, FORTRAN - это возможность, как и С++, и, благодаря Дирку Эддельбуэттелю и Ромену Франсуа, последнее гораздо проще сделать с пакетом rcpp.
Векторная функция возвращает вектор той же длины, что и один из его аргументов. Как правило, такую функцию можно получить, используя комбинации встроенных функций, таких как "+", cos
или exp
, которые также векторизованы.
vecexpcos <- function(x) exp(cos(x))
vecexpcos( (1:10)*pi )
> vecexpcos( (1:10)*pi )
# [1] 0.3678794 2.7182818 0.3678794 2.7182818 0.3678794 2.7182818 0.3678794 2.7182818 0.3678794 2.7182818
Если вам нужно использовать не-векторизованную функцию типа sum
, вам может потребоваться вызвать mapply
или Vectorize
, чтобы получить желаемое поведение.