R中向量和向量列表之间的角度 [英] Angle between vector and list of vectors in R
问题描述
当比较两个向量时,计算它们之间的角度很简单,但在 R 中,有效地计算向量和向量矩阵之间的角度明显更困难.
When comparing two vectors it is simple to calculate the angle between them, but in R it is noticeably harder to calculate the angle between a vector and a matrix of vectors efficiently.
假设你有一个二维向量 A=(2, 0) 和一个矩阵 B={(1,3), (-2,4), (-3,-3), (1,-4)}.我有兴趣计算 A 和 B 中向量之间的最小角度.如果我尝试使用
Say you have a 2D vector A=(2, 0) and then a matrix B={(1,3), (-2,4), (-3,-3), (1,-4)}. I am interested in working out the smallest angle between A and the vectors in B. If I try to use
min(acos( sum(a%*%b) / ( sqrt(sum(a %*% a)) * sqrt(sum(b %*% b)) ) ))
它失败了,因为它们是不一致的参数.
it fails as they are non-conformable arguments.
有没有类似上面的代码可以处理向量和矩阵?
Is there any code similar to that of above which can handle a vector and matrix?
注意:在多个来源中找到的解决方案存在被标记为重复的风险在这种情况下不适用
Note: At the risk of being marked as a duplicate the solutions found in several sources do not apply in this case
这样做的原因是我有一个很大的矩阵 X
,而 A
只是其中的一行.我仅根据每个向量的角度来减少元素的数量.B
的第一个元素是X
中的第一个元素,然后如果B
中的任何一个元素与下一个元素X的夹角[,2]
(此处为A
)大于一定容差,将其加入列表B
.我只是使用 B<-rbind(B,X[,2])
来做到这一点,所以这导致 B
成为一个矩阵.
The reason for this is I have a large matrix X
, and A
is just one row of this. I am reducing the number of elements based solely on the angle of each vector. The first element of B
is the first in X
, and then if the angle between any element in B
and the next element X[,2]
(here A
) is greater than a certain tolerance, this is added to the list B
. I am just using B<-rbind(B,X[,2])
to do this, so this results in B
being a matrix.
推荐答案
你没有详细描述 A 和 B 的格式,所以我假设它们是逐行矩阵.
You don't describe the format of A and B in detail, so I assume they are matrices by rows.
(A <- c(2, 0))
# [1] 2 0
(B <- rbind(c(1,3), c(-2,4), c(-3,-3), c(1,-4)))
# [,1] [,2]
# [1,] 1 3
# [2,] -2 4
# [3,] -3 -3
# [4,] 1 -4
<小时>
解决方案 1 使用 apply()
:
apply(B, 1, FUN = function(x){
acos(sum(x*A) / (sqrt(sum(x*x)) * sqrt(sum(A*A))))
})
# [1] 1.249046 2.034444 2.356194 1.325818
解决方案 2 使用 sweep()
:(将上面的 sum()
替换为 rowSums()
)
Solution 2 with sweep()
: (replace sum()
above with rowSums()
)
sweep(B, 2, A, FUN = function(x, y){
acos(rowSums(x*y) / (sqrt(rowSums(x*x)) * sqrt(rowSums(y*y))))
})
# [1] 1.249046 2.034444 2.356194 1.325818
解决方案 3 使用 split()
和 mapply
:
mapply(function(x, y){
acos(sum(x*y) / (sqrt(sum(x*x)) * sqrt(sum(y*y))))
}, split(B, row(B)), list(A))
# 1 2 3 4
# 1.249046 2.034444 2.356194 1.325818
这篇关于R中向量和向量列表之间的角度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!