Вычислить все попарные различия внутри вектора в R

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

Скажем, у меня есть вектор, v.

v<-c(1:4)

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

abs(1-2) = 1
abs(1-3) = 2
abs(1-4) = 3
abs(2-3) = 1
abs(2-4) = 2
abs(3-4) = 1

Результат будет вектором из 6 значений, которые являются результатом моих 6 сравнений:

output<- c(1,2,3,1,2,1)

Есть ли в R функция, которая может это сделать?

Ответы

Ответ 1

Пусть играют в гольф

abs(apply(combn(1:4,2), 2, diff))

@Ben, ваш убийца!

> system.time(apply(combn(1:1000,2), 2, diff))
   user  system elapsed 
   6.65    0.00    6.67 
> system.time(c(dist(1:1000)))
   user  system elapsed 
   0.02    0.00    0.01 
> system.time({
+ v <- 1:1000
+ z = outer(v,v,'-');
+ z[lower.tri(z)];
+ })
   user  system elapsed 
   0.03    0.00    0.03 

Кто знал, что этот элегантный (читаемый понятный/гибкий) код может быть настолько медленным.

Ответ 2

as.numeric(dist(v))

похоже, работает; он рассматривает v как матрицу столбца и вычисляет евклидово расстояние между строками, которое в этом случае равно sqrt((x-y)^2)=abs(x-y)

Если мы играем в гольф, то я предлагаю c(dist(v)), что эквивалентно, и я предполагаю, что это будет непобедимым.

@AndreyShabalin делает все возможное, чтобы использование method="manhattan", вероятно, было бы немного более эффективным, так как оно избегает возведения в квадрат/квадратного корня.

Ответ 3

Возможное решение:

z = outer(v,v,'-'); 
z[lower.tri(z)];

[1] 1 2 3 1 2 1