Предположим, у меня есть матрица размером 2 и функция, которая принимает 2-вектор в качестве одного из своих аргументов. Я хотел бы применить функцию к каждой строке матрицы и получить n-вектор. Как это сделать в R?
Например, я хотел бы вычислить плотность стандартного двухмерного нормального распределения по трем точкам:
bivariate.density(x = c(0, 0), mu = c(0, 0), sigma = c(1, 1), rho = 0){
exp(-1/(2*(1-rho^2))*(x[1]^2/sigma[1]^2+x[2]^2/sigma[2]^2-2*rho*x[1]*x[2]/(sigma[1]*sigma[2]))) * 1/(2*pi*sigma[1]*sigma[2]*sqrt(1-rho^2))
}
out <- rbind(c(1, 2), c(3, 4), c(5, 6))
Как применить функцию к каждой строке out
?
Как передать в функцию значения для других аргументов, помимо точек, указанным вами способом?
apply()
- он просматривается по строкам (когда второй аргумент равен 1, иначе по столбцам), а текущая строка (или столбец) всегда является первым аргументом. Вот как все определяется.MARGIN
аргумент. Здесь это означает применение функции к строкам (первое измерение вdim(M)
). Если бы было 2, он применил бы функцию к столбцам.Если вы хотите применить общие функции, такие как сумма или среднее значение, вам следует использовать
rowSums
или,rowMeans
поскольку они быстрее, чемapply(data, 1, sum)
подход. В противном случае придерживайтесьapply(data, 1, fun)
. Вы можете передать дополнительные аргументы после аргумента FUN (как уже предложил Дирк):Тогда вы можете сделать что-то вроде этого:
источник
Вот краткий пример применения функции к каждой строке матрицы. (Здесь примененная функция нормализует каждую строку до 1.)
Примечание: В результате от должны
apply()
было быть транспонированным с помощью ,t()
чтобы получить тот же формат, что и входной матрицаA
.Результат:
источник
Первым шагом будет создание функционального объекта, а затем его применение. Если вам нужен объект матрицы с таким же количеством строк, вы можете предварительно определить его и использовать форму object [], как показано (в противном случае возвращаемое значение будет упрощено до вектора):
Если вы хотите использовать параметры, отличные от параметров по умолчанию, вызов должен включать именованные аргументы после функции:
apply () также можно использовать с массивами более высокой размерности, а аргумент MARGIN может быть вектором или одним целым числом.
источник
Apply хорошо справляется со своей задачей, но довольно медленно. Может быть полезно использовать sapply и vapply. Также может быть полезен построчный метод dplyr. Давайте посмотрим на примере, как сделать построчное произведение любого фрейма данных.
Обратите внимание, что присвоение переменной перед использованием vapply / sapply / apply является хорошей практикой, так как это значительно сокращает время. Посмотрим результаты микробенчмарка
Внимательно посмотрите, как используется t ()
источник
b <- t(iris[1:10, 1:3])
иapply(b, 2 prod)
.Другой подход, если вы хотите использовать изменяющуюся часть набора данных вместо одного значения, - это использовать
rollapply(data, width, FUN, ...)
. Использование вектора ширины позволяет применить функцию к изменяющемуся окну набора данных. Я использовал это для создания процедуры адаптивной фильтрации, хотя она не очень эффективна.источник