【问题标题】:How to average multiple trajectories in R?如何平均R中的多个轨迹?
【发布时间】:2023-03-10 22:26:01
【问题描述】:

我正在尝试使用 R 可视化虚拟房间中多个参与者的轨迹。我有一个参与者从右侧进入(黑色方块)并向左侧移动,那里有一个出口门(红色方块)。有时在房间(圆圈)的中间有一个障碍物,参与者绕过它。 为了在同一张图上可视化多个参与者的轨迹(即多条线),我使用函数 plot 来设置图本身(和第一条线),然后我使用函数线添加其他轨迹。 下面你可以看到一个有两行的例子;在实验中,我有更多(因为现在我收集了大约 20 名参与者的数据。)

library(shape)
# black line 
pos_x <- c(5.04,4.68,4.39,4.09,3.73,3.37,3.07,2.77,2.47,2.11)
pos_z <- c(0.74,0.69,0.64,0.60,0.56,0.52,0.50,0.50,0.50,0.51)
df1 <- cbind.data.frame(pos_x,pos_z)
x.2 <- df1$pos_x
z.2 <- df1$pos_z
plot(x.2,z.2,type="l", xlim=range(x.2), ylim=c(-1,3.5), xlab="x", ylab="z", main = "Two trajectories")
filledrectangle(wx = 0.2, wy = 0.2,col = "black", mid = c(5.16, 1), angle = 0)
filledrectangle(wx = 0.2, wy = 0.2,col = "red", mid = c(2, 1), angle = 0)
plotcircle(mid = c(3.4, 1), r = 0.05) 

# red line 
pos_x <- c(5.14,4.84,4.24,3.64,3.34,2.74,2.15)
pos_z <- c(0.17,0.13,0.01,-0.2,0.01,0.10,0.17)
df2 <- cbind.data.frame(pos_x,pos_z)
x.3 <- df2$pos_x
z.3 <- df2$pos_z
lines(x.3, z.3, xlim=range(x.3), ylim=c(-1,3.5), pch=16, col="red")

我现在想做的是找到这两条线之间的平均值。理想情况下,我希望能够平均多条线并为标准差添加一个区间。

我尝试的第一件事是构建插值;问题是起点和终点不同,所以我不能平均点:

plot(x.2, z.2, xlim=range(x.2), ylim=c(-1,3.5), xlab="x", ylab="z", main = "Interpolation")
points(approx(x.2, z.2), col = 2, pch = "*")
points(x.3, z.3)
points(approx(x.3, z.3), col = 2, pch = "*")

然后我找到了一个建议here:使用R库dtw

我查过librarycompanion paper

这是论文中的一个典型示例,其中从参考心电图中提取了“两个不重叠的窗口”。数据集“aami3a”是一个时间序列对象。

library("dtw")
data("aami3a")
ref <- window(aami3a, start = 0, end = 2)
test <- window(aami3a, start = 2.7, end = 5)
alignment <- dtw(test, ref)
alignment$distance

问题在于,在所有这些示例中,数据要么构造为时间序列对象,要么这两行是公共矩阵的函数(另请参阅文档中的 R quickstart example 和其他 tutorial。)

如何重新组织我的数据以使该功能正常工作?或者您知道其他创建平均值的方法吗?

【问题讨论】:

  • 你对这里的“平均”有明确的定义吗?是按时间平均的吗?按开始和结束之间的时间比例?你这里没有时间变量,所以大概是后者?
  • 我正在考虑将平均值作为 z 维度上的一个位置。例如,平均“端点”(靠近红色方块)将介于 0.17(红线)和 0.51(黑线)之间。我认为只考虑位置坐标会使事情变得更容易。我应该添加时间变量吗?数据记录在 Unity 中,所以我确实有时间戳,但时间戳会因情况而异。

标签: r time-series data-visualization


【解决方案1】:

您可以映射从每条路径的起点到终点的等效点(即在每条路径的起点找到两条线之间的中点,在每条路径完成四分之一之后找到两条线之间的中点,在一半,最后等等。

这样做的方法是使用插值(通过approx):

pos_x_a <- c(5.04,4.68,4.39,4.09,3.73,3.37,3.07,2.77,2.47,2.11)
pos_z_a <- c(0.74,0.69,0.64,0.60,0.56,0.52,0.50,0.50,0.50,0.51)

pos_x_b <- c(5.14,4.84,4.24,3.64,3.34,2.74,2.15)
pos_z_b <- c(0.17,0.13,0.01,-0.2,0.01,0.10,0.17)

pos_t_a <- seq(0, 1, length.out = length(pos_x_a))
pos_t_b <- seq(0, 1, length.out = length(pos_x_b))

a_x <- approx(pos_t_a, pos_x_a, seq(0, 1, 0.01))$y
a_y <- approx(pos_t_a, pos_z_a, seq(0, 1, 0.01))$y
b_x <- approx(pos_t_b, pos_x_b, seq(0, 1, 0.01))$y
b_y <- approx(pos_t_b, pos_z_b, seq(0, 1, 0.01))$y

plot(a_x, a_y, type = "l", ylim = c(-1, 3))
lines(b_x, b_y, col = "red")
lines((a_x + b_x)/2, (a_y + b_y)/2, col = "blue", lty = 2)

通过连接用于获取平均值的每条线上的点,我们可以更好地了解这种平均是如何发生的:

for(i in seq_along(a_x)) segments(a_x[i], a_y[i], b_x[i], b_y[i], col = "gray")

【讨论】:

  • 谢谢艾伦,这是一个很好的解决方案!要平均多条线,我可以将额外的点相加并平均,对吗?假设我有第三个轨迹数据集 c。那将是lines((a_x + b_x + c_x)/3, (a_y + b_y + c_y)/3)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-24
  • 1970-01-01
  • 2013-07-22
  • 2019-10-10
  • 1970-01-01
  • 2021-08-28
相关资源
最近更新 更多