【问题标题】:compute all pairwise differences within a vector in R计算 R 中向量内的所有成对差异
【发布时间】:2014-08-10 11:31:26
【问题描述】:

有几篇关于计算向量之间的成对差异的帖子,但我找不到如何计算向量内的所有差异。

假设我有一个向量,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 中有没有可以做到这一点的函数?

【问题讨论】:

    标签: 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 
    

    谁知道优雅(可读/灵活)的代码会这么慢。

    【讨论】:

    • 你能打败c(dist(v))(10 个字符)吗? (如果你用v 代替1:4,你的可能会稍微短一些)
    • 嗯!我认为@BenBolker 会赢得比赛。我假设我的示例在一行中引入了 3 个常用函数作为奖励。
    • 他们都运作良好。我接受了这个答案,因为我可以更清楚地理解发生了什么。此外,我可以轻松修改此代码以执行其他成对操作(即计算同一向量的成对和)。我不能用 dist() 函数做到这一点。
    • 我们都可以切换到 Julia :-)
    • +1 combn 有一个 FUN 参数,所以你可以这样做:combn(v,2,FUN=diff)
    【解决方案2】:
    as.numeric(dist(v))
    

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

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

    @AndreyShabalin 指出使用 method="manhattan" 可能会稍微更有效,因为它避免了平方/平方根的问题。

    【讨论】:

    • 为避免平方根,您可以使用另一个指标:as.vector(dist(v, method = "manhattan"))
    • 嗯,有些东西搞砸了。不知何故,解决方案偏离了 100 倍。
    【解决方案3】:

    一个可能的解决方案是:

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

    【讨论】:

    • 分号是不必要的,而且效率有点低(计算完整的矩阵),但其他方面非常好。
    • 在看这里之前我有sapply(v, "-", v) outer 不错!
    猜你喜欢
    • 2018-07-04
    • 2012-03-20
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多