Ответ 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.