我在R中有一个包含2列的数据框,名为x和y(坐标)。数据框代表一个旅程,每条线代表下一个时间点的位置。
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代码。它会创建一个名为segment的新列。
%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
答案 0 :(得分:2)
如果您的数据集是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]
跳转到超出截止值的第一行)尝试提出一个完全矢量化的解决方案会很有趣,但这应该没问题。您的数据集有多大?