R: как хранить вектор векторов

Я пытаюсь написать функцию для определения евклидова расстояния между x (одна точка) и y (набор из n точек). Как мне передать y в функцию? До сих пор я использовал такую ​​матрицу:

     [,1] [,2] [,3]
[1,]    0    2    1
[2,]    1    1    1

Что передаст точки (0,2,1) и (1,1,1) этой функции.

Однако, когда я передаю x как нормальный вектор (столбец), две переменные в функции не совпадают. Мне либо нужно транспонировать x или y, либо сохранить вектор векторов другим способом.

Мой вопрос: каков стандартный способ сохранить более одного вектора в R? (моя матрица y)
Это просто моя y транспонированная или, может быть, список или фрейм данных?


person Alexander Engelhardt    schedule 13.11.2010    source источник
comment
Я бы составил список с комбинациями точек, по которым вы хотите рассчитать расстояние. Вы передаете это функции применения и работаете оттуда.   -  person Roman Luštrik    schedule 13.11.2010


Ответы (2)


Стандартного способа нет, поэтому нужно просто выбрать наиболее эффективный, что, с другой стороны, зависит от того, как этот вектор векторов выглядит сразу после создания (лучше избегать любых преобразований, которые не нужны) и от скорости сама функция.

Я считаю, что data.frame со столбцами x, y и z должен быть хорошим выбором; тогда функция расстояния будет довольно простой и быстрой:

d<-function(x,y) sqrt((y$x-x[1])^2+(y$y-x[2])^2+(y$z-x[3])^2)
person mbq    schedule 13.11.2010
comment
Спасибо! Как бы я это сделал, если бы хотел, чтобы функция обрабатывала n-мерные точки? - person Alexander Engelhardt; 13.11.2010
comment
Для использования правила повторного использования sqrt(colSums((t(y)-x)^2)) потребуется одна транспозиция. - person mbq; 14.11.2010

Функция apply с аргументом margin = 1 кажется наиболее очевидной:

> x
     [,1] [,2] [,3]
[1,]    0    2    1
[2,]    1    1    1
> apply(x , 1, function(z) crossprod(z, 1:length(z) )  )
[1] 7 6
> 2*2+1*3
[1] 7
> 1*1+2*1+3*1
[1] 6

Итак, если вам нужны расстояния, то, похоже, работает квадратный корень из перекрестного произведения различий в выбранной точке:

> apply(x , 1, function(z) sqrt(sum(crossprod(z -c(0,2,2), z-c(0,2,2) ) ) ) )
[1] 1.000000 1.732051
person IRTFM    schedule 13.11.2010
comment
Это было бы довольно медленно для больших данных. - person mbq; 14.11.2010