我在 R 中有一个数据框,其中包含名为 x 和 y (坐标)的 2 列。数据框代表一个旅程,每条线代表下一个时间点的位置。
x y seconds
1 0.0 0.0 0
2 -5.8 -8.5 1
3 -11.6 -18.2 2
4 -16.9 -30.1 3
5 -22.8 -40.8 4
6 -29.0 -51.6 5
我需要将旅程分成几段,一旦距上一段起点的距离超过某个阈值(例如 200),每个段就开始。
我最近从使用 SAS 转向使用 R,这是我第一次遇到在 SAS 中可以轻松完成的任何事情,但我什至想不出在 R 中解决问题的方法。
我已经发布了 SAS 代码,我将在下面使用它来完成相同的工作。它创建一个名为“段”的新列。
%let cutoff=200;
data segments;
set journey;
retain segment distance x_start y_start;
if _n_=1 then do;
x_start=x;
y_start=y;
segment=1;
distance=0;
end;
distance + sqrt((x-x_start)**2+(y-y_start)**2);
if distance>&cutoff then do;
x_start=x;
y_start=y;
segment+1;
distance=0;
end;
keep x y seconds segment;
run;
编辑:示例输出 如果截止值为 200,那么所需输出的示例将类似于...
x y seconds segment
1 0.0 0.0 0 1
2 40.0 30.0 1 1
3 80.0 60.0 2 1
4 120.0 90.0 3 1
5 160.0 120.0 4 2
6 120.0 150.0 5 2
7 80.0 180.0 6 2
8 40.0 210.0 7 2
9 0.0 240.0 8 3
最佳答案
如果您的数据集是dd
,类似于
cutoff <- 200
origin <- dd[1,c("x","y")]
cur.seg <- 1
dd$segment <- NA
for (i in 1:nrow(dd)) {
dist <- sqrt(sum((dd[i,c("x","y")]-origin)^2))
if (dist>cutoff) {
cur.seg <- cur.seg+1
origin <- dd[i,c("x","y")]
}
dd$segment[i] <- cur.seg
}
应该可以工作。有一些改进(计算当前原点到所有行的距离可能更有效,然后使用which(dist>cutoff)[1]
跳转到第一行超出了截止值),尝试提出一个完全矢量化的解决方案会很有趣,但这应该没问题。您的数据集有多大?
关于r - 根据先前行的值按行分割数据帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27680772/