在 data.table 中使用滚动函数计算点之间的欧氏距离
Calculate Euclidean distance between points with rolling function in data.table
我有一个 data.table,在不同区域有横断面,坐标 x 和 y 投影为 UTM 36S。
如何使用滚动函数计算每个区域 data.table
连续点之间的(欧几里德)距离?
x y date area
1: 860030 9956743 2019-10-17 13:40:36 area1
2: 860025 9956762 2019-10-17 13:42:04 area1
3: 860025 9956764 2019-10-17 13:43:06 area1
4: 859984 9956795 2019-10-17 13:44:06 area1
5: 859928 9956803 2019-10-17 13:45:06 area1
6: 852010 9945485 2018-12-06 06:12:04 area2
7: 852024 9945476 2018-12-06 06:12:15 area2
8: 852033 9945470 2018-12-06 06:12:23 area2
输入 x 对象:
structure(list(x = c(860030.089581219, 860024.678438056, 860024.669866417,
859984.428586571, 859928.100890497, 852009.95451107, 852024.297711228,
852033.150084026), y = c(9956743.22114593, 9956761.52220698,
9956763.54512543, 9956795.19408176, 9956802.56503778, 9945485.12489829,
9945475.70943483, 9945469.72972126), date = structure(c(1571319636,
1571319724, 1571319786, 1571319846, 1571319906, 1544076724, 1544076735,
1544076743), class = c("POSIXct", "POSIXt"), tzone = "UTC"),
area = c("area1", "area1", "area1", "area1", "area1", "area2",
"area2", "area2")), row.names = c(NA, -8L), class = c("data.table",
"data.frame"), .internal.selfref = <pointer: 0x558bcca1a3f0>, index = integer(0))
这里有两个选项:
1) 使用 frollapply
:
library(data.table)
setDT(DT)[, sqrt(Reduce(`+`, frollapply(.SD, 2L, function(v) diff(v)^2))), area, .SDcols=x:y]
由于 frollapply
将 FUN
分别应用于每一列,您可以在求和和取平方根之前将欧氏距离计算分成 2 份(对于 x 和 y)。
2) 使用 shift
:
DT[, sqrt((x - shift(x))^2 + (y - shift(y))^2), area]
输出:
[1] NA 19.084269 2.022937 51.195869 56.807925 13812.367407 17.157457 10.682765
我有一个 data.table,在不同区域有横断面,坐标 x 和 y 投影为 UTM 36S。
如何使用滚动函数计算每个区域 data.table
连续点之间的(欧几里德)距离?
x y date area
1: 860030 9956743 2019-10-17 13:40:36 area1
2: 860025 9956762 2019-10-17 13:42:04 area1
3: 860025 9956764 2019-10-17 13:43:06 area1
4: 859984 9956795 2019-10-17 13:44:06 area1
5: 859928 9956803 2019-10-17 13:45:06 area1
6: 852010 9945485 2018-12-06 06:12:04 area2
7: 852024 9945476 2018-12-06 06:12:15 area2
8: 852033 9945470 2018-12-06 06:12:23 area2
输入 x 对象:
structure(list(x = c(860030.089581219, 860024.678438056, 860024.669866417,
859984.428586571, 859928.100890497, 852009.95451107, 852024.297711228,
852033.150084026), y = c(9956743.22114593, 9956761.52220698,
9956763.54512543, 9956795.19408176, 9956802.56503778, 9945485.12489829,
9945475.70943483, 9945469.72972126), date = structure(c(1571319636,
1571319724, 1571319786, 1571319846, 1571319906, 1544076724, 1544076735,
1544076743), class = c("POSIXct", "POSIXt"), tzone = "UTC"),
area = c("area1", "area1", "area1", "area1", "area1", "area2",
"area2", "area2")), row.names = c(NA, -8L), class = c("data.table",
"data.frame"), .internal.selfref = <pointer: 0x558bcca1a3f0>, index = integer(0))
这里有两个选项:
1) 使用 frollapply
:
library(data.table)
setDT(DT)[, sqrt(Reduce(`+`, frollapply(.SD, 2L, function(v) diff(v)^2))), area, .SDcols=x:y]
由于 frollapply
将 FUN
分别应用于每一列,您可以在求和和取平方根之前将欧氏距离计算分成 2 份(对于 x 和 y)。
2) 使用 shift
:
DT[, sqrt((x - shift(x))^2 + (y - shift(y))^2), area]
输出:
[1] NA 19.084269 2.022937 51.195869 56.807925 13812.367407 17.157457 10.682765