基于先前的行值逐行分割数据

时间:2014-12-28 21:31:15

标签: r dataframe sas

我在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

1 个答案:

答案 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]跳转到超出截止值的第一行)尝试提出一个完全矢量化的解决方案会很有趣,但这应该没问题。您的数据集有多大?

相关问题