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

Как определить векторную функцию в R

Как название, я хотел бы знать, как определить векторную функцию в R.

  • Это просто с помощью цикла в функции?
  • Является ли этот метод эффективным?
  • А какая лучшая практика?
4b9b3361

Ответ 1

Цикл на уровне 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.

Ответ 2

Векторная функция возвращает вектор той же длины, что и один из его аргументов. Как правило, такую ​​функцию можно получить, используя комбинации встроенных функций, таких как "+", 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, чтобы получить желаемое поведение.