【问题标题】:sapply in R over a vector with individual elements of another vectorsapply 在 R 中使用另一个向量的单个元素的向量
【发布时间】:2016-03-24 11:08:26
【问题描述】:

我有两个向量 xcen。假设x 的长度为10cen 的长度为3。我想找到xcen 的各个点之间的欧几里得距离。

欧式距离函数定义为: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 函数?任何帮助,将不胜感激。提前致谢。

【问题讨论】:

  • 您的代码基本上是这样做的:sapply(1:length(x),function(m) euc.dist(x[m],cen)) 它将euc.dist 函数应用于每个x 元素到整个向量cen。一种解决方案是排列您的 xcen 向量,以便将相应的 x1x2 值插入 euc.dist
  • @road_to_quantdom:啊,我知道现在发生了什么。对不起,我不明白你所说的“线xcen向量”是什么意思
  • 查看outer函数,例如outer(cen,x,"-")
  • @MaratTalipov outer 确实适用于 "-" 操作,但 outer(cen,x,"euc.dist") 给出以下错误 - Error in outer(cen, x, euc.dist) : dims [product 30] do not match the length of object [1]

标签: r sapply euclidean-distance


【解决方案1】:

您的 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

【讨论】:

  • 我明白了。所以函数Vectorize() 是mapply 的包装器。这会做得很好。非常感谢!我没有意识到像"-" 和其他操作是按定义矢量化的,而euc.dist 不是。
  • 我以前从未在这里使用过 Vectorize,我很惊讶我没有。甚至有必要使用 sapply 吗?如果我定义 seqv1 <- function(x,y) Vectorize(seq)(y,x) 然后 seqv2 <- function(x,y) Vectorize(seqv1)(y,x) 这会向量化两者吗?
【解决方案2】:

这个怎么样? 因为你想要所有的因素组合

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

【讨论】:

  • 谢谢!此解决方法确实有效。但是,我将使用矢量x,其长度将达到数十万,而cen 将很小。以这种方式扩展数据会过度增加数据大小。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-28
  • 2015-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-20
相关资源
最近更新 更多