如何计算R中一系列样本中两条线向量之间的角度列表?
我正在使用二维笛卡尔坐标(即地标)制作生物标本的几何形态测量数据集。我对该数据集感兴趣的一部分是生成重要地标之间的距离和地标向量之间的角度的数据框架,并在所有样本中使用同源坐标进行进一步比较。点之间的距离不是问题,但当我试图计算每个样本的角度时,我遇到了问题如何计算R中一系列样本中两条线向量之间的角度列表?,r,geometry,trigonometry,computational-geometry,R,Geometry,Trigonometry,Computational Geometry,我正在使用二维笛卡尔坐标(即地标)制作生物标本的几何形态测量数据集。我对该数据集感兴趣的一部分是生成重要地标之间的距离和地标向量之间的角度的数据框架,并在所有样本中使用同源坐标进行进一步比较。点之间的距离不是问题,但当我试图计算每个样本的角度时,我遇到了问题 data<-array(data=c(-0.2411,-0.0677,0.1147,0.0085,0.060183,-0.029954,0.012111,0.000462,-0.22509,-0.09437,0.09135,0.003
data<-array(data=c(-0.2411,-0.0677,0.1147,0.0085,0.060183,-0.029954,0.012111,0.000462,-0.22509,-0.09437,0.09135,0.00367,0.0764,-0.0202,-0.0182,-0.0045,-0.2223,-0.1001,0.0553,-0.0617,0.06122,-0.02366,0.00577,-0.01557),c(4,2,3))
我试图找到一种方法来计算一系列样本上代表相同角度的线向量之间的角度(向量描述了一个具有生物学意义的特征,该特征存在于我的数据集中的所有样本中)。我用来操作形态测量数据的R包将地标作为类array()
的三维对象输出,其中行是地标,列是坐标的尺寸,第三维是样本。以下是样本数据中三个样本的地标坐标
, , Specimen1
X Y
1 -0.2411 0.060183
2 -0.0677 -0.029954
3 0.1147 0.012111
4 0.0085 0.000462
, , Specimen2
X Y
1 -0.22509 0.0764
2 -0.09437 -0.0202
3 0.09135 -0.0182
4 0.00367 -0.0045
, , Specimen3
X Y
1 -0.2223 0.06122
2 -0.1001 -0.02366
3 0.0553 0.00577
4 -0.0617 -0.01557
下面是一个可读数组,它复制了我作为前三个样本的输出而获得的数据
data<-array(data=c(-0.2411,-0.0677,0.1147,0.0085,0.060183,-0.029954,0.012111,0.000462,-0.22509,-0.09437,0.09135,0.00367,0.0764,-0.0202,-0.0182,-0.0045,-0.2223,-0.1001,0.0553,-0.0617,0.06122,-0.02366,0.00577,-0.01557),c(4,2,3))
然后以某种方式将其添加到数据帧中,使其看起来像这样:
Distance Angle1 Angle2
Specimen1 100 146 100
Specimen2 100 152 100
Specimen3 100 135 100
Angle2的距离和值只是填充数字,以显示我试图实现的格式
我已经尝试在mathlib包中使用angle()
函数,在Morpho包中使用angle.calc()
函数。下面是我使用angle()
函数计算角度的代码
vector1<-data[1,,]-data[2,,]
vector2<-data[3,,]-data[4,,]
angle(as.vector(vector1),as.vector(vector2),degree=TRUE)
vector1首先,给2x3
矩阵命名vector1
有点混乱。除此之外,您可以使用matlib::angle
计算角度
library(matlib)
phi <- setNames(mapply(
function(x1, x2) angle(x1, x2),
as.data.frame(vector1), as.data.frame(vector2)),
paste0("Specimen", 1:ncol(vector1)))
phi
#Specimen1 Specimen2 Specimen3
# 146.2674 152.4439 134.8753
首先,给一个2x3
矩阵命名vector1
有点混乱。除此之外,您可以使用matlib::angle
计算角度
library(matlib)
phi <- setNames(mapply(
function(x1, x2) angle(x1, x2),
as.data.frame(vector1), as.data.frame(vector2)),
paste0("Specimen", 1:ncol(vector1)))
phi
#Specimen1 Specimen2 Specimen3
# 146.2674 152.4439 134.8753
一般来说,您可能会发现首先以长/整齐的格式获取数据更简单。这使得分组和聚合更加容易,这是矢量化/映射操作真正发挥作用的地方
使用您提供的数据,有一种方法可以做到这一点:
library(matlib)
library(tidyverse)
n_specimen <- ncol(vector1)
data.frame(t(vector1)) %>%
rename_all(~str_replace(., "X", "v1_")) %>%
bind_cols(
data.frame(t(vector2)) %>%
rename_all(~str_replace(., "X", "v2_"))
) %>%
mutate(specimen = paste0("Specimen", 1:n_specimen)) %>%
pivot_longer(-specimen, names_to = "vector", values_to = "value") %>%
separate(vector, into = c("vector", "ix"), sep = "_", remove = TRUE) %>%
group_by(specimen) %>%
summarise(angle = angle(value[vector == "v1"], value[vector == "v2"]))
specimen angle
<chr> <dbl>
1 Specimen1 146.
2 Specimen2 152.
3 Specimen3 135.
每一列都有一个独特的信息级别,您现在可以按照所需的特定级别进行分组和总结。一般来说,您可能会发现首先以长/整齐的格式获取数据更简单。这使得分组和聚合更加容易,这是矢量化/映射操作真正发挥作用的地方
使用您提供的数据,有一种方法可以做到这一点:
library(matlib)
library(tidyverse)
n_specimen <- ncol(vector1)
data.frame(t(vector1)) %>%
rename_all(~str_replace(., "X", "v1_")) %>%
bind_cols(
data.frame(t(vector2)) %>%
rename_all(~str_replace(., "X", "v2_"))
) %>%
mutate(specimen = paste0("Specimen", 1:n_specimen)) %>%
pivot_longer(-specimen, names_to = "vector", values_to = "value") %>%
separate(vector, into = c("vector", "ix"), sep = "_", remove = TRUE) %>%
group_by(specimen) %>%
summarise(angle = angle(value[vector == "v1"], value[vector == "v2"]))
specimen angle
<chr> <dbl>
1 Specimen1 146.
2 Specimen2 152.
3 Specimen3 135.
每一列都有一个独特的信息级别,您现在可以根据所需的具体程度进行分组和总结。您能否更新您的示例,以说明您希望如何处理“每个样本的多个角度”?解决每个样本只进行一次比较(这是您现在期望的输出)比解决任意数量的比较要简单。@andrew_reece示例已更新。总的来说,我想尝试为每个角度写一列,并为每个角度写一个单独的方程。每个预期角度列代表了在研究领域感兴趣的每个样本上可测量的特定特征。感谢更新。请查看答案,并在各自的评论源中回复,让我们知道我们是否遗漏了任何内容。您能否更新您的示例,以说明您希望如何处理“每个样本的多个角度”?解决每个样本只进行一次比较(这是您现在期望的输出)比解决任意数量的比较要简单。@andrew_reece示例已更新。总的来说,我想尝试为每个角度写一列,并为每个角度写一个单独的方程。每个预期角度列代表了在研究领域感兴趣的每个样本上可测量的特定特征。感谢更新。请查看答案,并在各自的评论源中回复,让我们知道我们是否遗漏了任何内容。我更新了问题,以了解矩阵为何采用2x3格式。基本上,它是一个x,y向量,由两个点减去另一个点得到,每列代表一个样本。@user2352714(从R结构的角度来看)将这些向量存储在列表中会更有意义。不仅向量
s与向量相关;使用*apply
系列中的函数,还可以轻松地迭代列表
元素。在你编辑之后,我现在不清楚这是否解决了你的问题。我将向您展示如何为每个样本创建角度矩阵。这解决了你的问题吗?老实说,我甚至不确定创建向量的最佳方法是什么。我对R不是很在行。我试图找到所有样本的点1-2和3-4形成的线之间的角度。角度函数表示它们需要矢量格式的信息,但没有说明如何从笛卡尔数据中获取,我能找到的最好结果是两个地标之间的x和y差异。不清楚函数是否需要线性向量或类vector
的对象或什么。@user2352714 R中的向量是包含相同类型元素的基本数据结构c(1.0,10,20)
是一个数值的
向量c(“A”、“O”、“L”)
是一个字符
向量;等等函数角度
需要一个数值
向量,请参见文档?角度
中给出的示例。我更新了问题,以了解矩阵为何采用2x3格式。基本上,它是一个x,y向量,由两个点减去另一个点得到,每列代表一个单独的sp