我在p
中有一组2D点存储:
x <- c(0, 1, 2, 3, 4)
y <- c(0, 1, 2, 3, 4)
p <- cbind(x,y)
我需要计算每个连续点之间的距离,我计算距离的函数是hypotenuse
(实际上我的问题有点不同,因为我有一个经度,纬度值列表,我需要使用{来自distVincentyEllipsoid
包的{1}}。
geosphere
我想使用hypotenuse <- function(p1,p2)
{
sqrt((p1[1]-p2[1])^2+(p1[2]-p2[2])^2)
}
,但在我看来,我无法将diff
函数传递给自定义“差异”函数,所以我的解决方案到现在为止如下:
diff
我阅读了问题A iterative and lagging function similar to diff in R, but not just difference?,并尝试以这种方式使用distances <- c()
for(i in 2:nrow(p))
{
distances <- c(distances,hypotenuse(p[i,],p[i-1,]))
}
包中的rollapply
函数:
zoo
但我收到了错误
FUN错误(数据[posns],...):
参数“p2”缺失,没有 默认
因此在我看来,FUN不能是二元函数。
是否可以使用library(zoo)
rollapply(p,width=1,FUN=hypotenuse)
功能解决我的问题?
答案 0 :(得分:5)
以下是一些方法:
> # 1a
> sqrt(rowSums(diff(p)^2))
[1] 1.414214 1.414214 1.414214 1.414214
> # 1b
> sqrt(diff(p[, 1])^2 + diff(p[, 2])^2)
[1] 1.414214 1.414214 1.414214 1.414214
> # 2a
> library(zoo)
> rollapply(p, 2, dist, by.column = FALSE)
[1] 1.414214 1.414214 1.414214 1.414214
> # 2b
> rollapply(p, 2, function(x) unname(hypotenuse(x[1, ], x[2, ])), by.column = FALSE)
[1] 1.414214 1.414214 1.414214 1.414214
> # 2c
> rollapply(p, 2, function(x) sqrt(sum(diff(x)^2)), by.column = FALSE)
[1] 1.414214 1.414214 1.414214 1.414214
ADDED:重新排列并添加到解决方案中。
答案 1 :(得分:4)
由于这似乎是一个可接受的替代方案,您可以对整个计算进行矢量化:
sqrt((p[2:5,1] - p[1:4,1])^2 + (p[2:5,2] - p[1:4,2])^2)
您可以使用head
和tail
来推广索引,或者如果您愿意,可以使用否定索引。例如,
sqrt((p[-1,1] - p[-nrow(p),1])^2 + (p[-1,2] - p[-nrow(p),2])^2)
答案 2 :(得分:2)
我认为这个选项有点干净,因为你可以保持功能独立,不需要修改功能,如果它是一个复杂的功能,或者如果用户没有直接访问可能会很烦人对它(这可能是他感兴趣的实际功能的情况):
p.list <- unname(split(p, row(p))) # `p` is as produced in question
mapply(hypotenuse, head(p.list, -1L), tail(p.list, -1L))
# [1] 1.414214 1.414214 1.414214 1.414214
使用相同的hypotenuse
问题海报。这里的关键是将原始的p矩阵转换为包含x-y坐标对的列表,然后允许我们使用mapply
。