2015-12-17 3 views
1

У меня есть два вектора x и cen. Скажем, длина x составляет 10, а длина cen составляет 3. Я хочу найти евклидову расстояние между x и отдельными точками cen.sapply in R над вектором с отдельными элементами другого вектора

Евклидова функция расстояния определяются как: euc.dist <- function(x1, x2) sqrt(sum((x1 - x2)^2))

Я видел, что sapply работает с отрицанием "-" оператора так:

> x 
[1] 23 4 65 8 9 23 90 76 55 7 
> cen 
[1] 23 4 65 
> sapply(x,"-",cen) 
    [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] 
[1,] 0 -19 42 -15 -14 0 67 53 32 -16 
[2,] 19 0 61 4 5 19 86 72 51  3 
[3,] -42 -61 0 -57 -56 -42 25 11 -10 -58 

Здесь каждый каждое значение в пределах cen вектора действует по всем x вектору ,

Но когда я пытаюсь использовать функцию euc.dist вместо "-", тогда я получаю только один вектор как результат вместо матрицы 3x10.

> sapply(x,"euc.dist",cen) 
[1] 46.09772 63.89053 74.06079 59.07622 57.93962 46.09772 111.84811 90.07774 61.03278 60.24118 

Любые причины, почему это происходит? Нужно ли определять функцию euc.dist другим способом? Любая помощь будет оценена по достоинству. Заранее спасибо.

+0

ваш код в основном делает это: 'sapply (1: длина (х), функция (м) euc.dist (х [м] , cen)) ' Он применяет функцию' euc.dist' к каждому элементу 'x' ко всему вектору' cen'. Одно из решений состоит в том, чтобы выстроить ваши векторы 'x' и' cen', чтобы у вас были соответствующие значения 'x1' и' x2' для подключения к 'euc.dist'. –

+0

@road_to_quantdom: ах, я понимаю, что происходит сейчас. Извините, я не понимаю, что вы подразумеваете под «линиями' x' и 'cen' векторы» – Sid

+0

Посмотрите на функцию 'external', например. 'external (cen, x," - ")' –

ответ

2

Ваш euc.dist функция не векторизации, так как можно было бы легко проверить:

euc.dist(x[1],cen) 
[1] 46.09772 

а то, что вы, вероятно, хотите есть:

> Vectorize(euc.dist)(x[1],cen) 
[1] 0 19 42 

(Для получения дополнительной информации используйте ?Vectorize).

Таким образом, в вашем случае простое решение будет:

> sapply(x,Vectorize(euc.dist),cen) 

    [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] 
[1,] 0 19 42 15 14 0 67 53 32 16 
[2,] 19 0 61 4 5 19 86 72 51  3 
[3,] 42 61 0 57 56 42 25 11 10 58 
+0

Я вижу. Таким образом, функция Vectorize() 'является оболочкой для mapply. Это будет хорошо. Большое спасибо! Я не понимал, что операции, такие как '' - "и другие, векторизованы по определению, а' euc.dist' - нет. – Sid

+0

Я никогда не использовал Vectorize здесь раньше, и я был поражен, что не знал. Нужно ли даже использовать sapply?если я определяю 'seqv1 <- function (x, y) Vectorize (seq) (y, x)', а затем 'seqv2 <- function (x, y) Vectorize (seqv1) (y, x)' Будет ли это просто векторизовать оба ? – Shape

1

как насчет этого? , так как вы хотите, чтобы все комбинации факторов

datas <- expand.grid(x = x,cen = cen) 
datas$euclid = apply(datas,1,function(rowval) euc.dist(rowval[1], rowval[2])) 
+0

Спасибо! Это обходное решение действительно работает. Однако я буду работать с вектором 'x', который будет длиной в сотни тысяч, тогда как' cen' будет небольшим. Расширение данных таким образом увеличит этот размер данных слишком сильно. – Sid

Смежные вопросы