计算R中向量内的所有成对差异

col*_*lin 19 r

关于矢量之间的计算成对差异有几个帖子,但我找不到如何计算矢量中的所有差异.

说我有一个矢量,v.

v<-c(1:4)
Run Code Online (Sandbox Code Playgroud)

我想生成第二个向量,它是向量中所有成对差异的绝对值.相近:

abs(1-2) = 1
abs(1-3) = 2
abs(1-4) = 3
abs(2-3) = 1
abs(2-4) = 2
abs(3-4) = 1
Run Code Online (Sandbox Code Playgroud)

输出将是6个值的向量,这是我的6次比较的结果:

output<- c(1,2,3,1,2,1)
Run Code Online (Sandbox Code Playgroud)

R中有一个可以做到这一点的功能吗?

Ben*_*ker 19

as.numeric(dist(v))
Run Code Online (Sandbox Code Playgroud)

似乎工作; 它将v列视为列矩阵并计算行之间的欧几里德距离,在本例中为sqrt((x-y)^2)=abs(x-y)

如果我们正在打高尔夫球,那么我会提供c(dist(v)),这是相同的,我猜这将是无与伦比的.

@AndreyShabalin指出,使用它method="manhattan"可能会稍微提高效率,因为它避免了平方/平方根的东西.

  • 为了避免平方根,你可以使用另一个指标:`as.vector(dist(v,method ="manhattan"))`. (2认同)

mlt*_*mlt 14

我们打高尔夫球吧

abs(apply(combn(1:4,2), 2, diff))
Run Code Online (Sandbox Code Playgroud)

@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 
Run Code Online (Sandbox Code Playgroud)

谁知道优雅(易读易懂/灵活)的代码可能会很慢.

  • +1`combn`有一个'FUN`参数,所以你可以这样做:`combn(v,2,FUN = diff)` (5认同)
  • 你能击败`c(dist(v))`(10个字符)吗?(如果用'v`代替`1:4`,你的可能会略短一些) (3认同)

And*_*lin 12

可能的解决方案是:

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

[1] 1 2 3 1 2 1
Run Code Online (Sandbox Code Playgroud)

  • 分号是不必要的,并且温和效率低(计算完整矩阵)但其他方面非常好. (2认同)