Если я хочу вычислить n-мерное расстояние двух векторов, я могу использовать функцию, такую как:
a = c(1:10)
b = seq(20, 23, length.out = length(a))
test_fun =
function(x,y) {
return(
sqrt(
sum(
(x - y) ^ 2
)
)
)
}
n_distance = test_fun(a,b)
Теперь я хочу расширить это до параметра матрицы: я хочу вычислитьn-мерное расстояние для каждой пары строк двух матриц.
set.seed(123)
a_mtx = matrix(1:30, ncol = 5)
b_mtx = matrix(sample(1:15,15), ncol = 5)
n_distance_mtx =
matrix(
NA,
nrow = nrow(b_mtx),
ncol = nrow(a_mtx)
)
for(i in 1:nrow(b_mtx)) {
for(j in 1:nrow(a_mtx)) {
n_distance_mtx[i,j] =
test_fun(a_mtx[j,], b_mtx[i,])
}
}
Где каждый столбец n_distance_mtx
содержит метрики расстояния между каждой строкой a_mtx
и b_mtx
(т. е. n_distance_mtx[,1]
это расстояние между a_mtx[1,]
и b_mtx[1:3,]
.
Если я вычислю значения столбца на n_distance_mtx
, я могу получить среднее расстояние между каждой строкой в a_mtx
и всеми строками b_mtx
.
colMeans(n_distance_mtx)
#[1] 23.79094 24.90281 26.15618 27.53303 29.01668 30.59220
Итак 23.79094 - это среднее расстояние между a_mtx[1,]
и b_mtx[1:3,]
, а 24.90281 - среднее расстояние между a_mtx[2,]
и b_mtx[1:3,]
, ии так далее.
Вопрос: Как я могу прийти к тому же решению без использования циклов for?
Я хочу применить этот метод к матрицам с гораздо большей размерностью (порядка сотен тысяч строк). Глядя на это и это , кажется, должен быть способ сделать это с помощью функции Vectorize
d outer
, но я не смог сгенерировать такую функцию.
test_fun_vec =
Vectorize(
function(x,y) {
outer(
x,
y,
test_fun
)
}
)
test_fun_vec(a_mtx,b_mtx)
#[1] 4 0 2 7 4 6 3 5 1 5 7 5 10 0 9 11 15 17 8 11 9 12 10 16
#[25] 10 22 20 25 15 24