用“间隙公差”对顺序值进行分组

时间:2019-11-14 12:54:32

标签: r

我有这个df

FRAME   TRACK_ID   SUM   TC_17
1       15         0     1
2       15         0     1
3       15         0     1
4       15         0     -1
5       15         0     1
6       15         0     1
7       15         0     -1
8       15         0     -1
9       15         0     1
10      15         0     1

现在,我正在使用此代码获取TC_17的值为1的帧:

for (i in 1:length(IDs)) {
  temp <- get(paste("TRACK_", IDs[i], sep = ""))
  temp3 <- paste("TRACK_", IDs[i], sep = "")
  if (ncol(temp)==3) {
    print(paste("No contacts detected for Track", IDs[i]))
    next
  }
  for (j in 4:ncol(temp)) {
    contact <- which(temp[,j] == 1) - 1
    contact <- sort(contact)
    Contact_No <- cumsum(c(1, abs(contact[-length(contact)] - contact[-1]) > 1))
    temp2 <- by(contact, Contact_No, identity)
  }
  assign(paste(temp3, colnames(temp)[j], sep = "_"), temp2)
}

这将返回列表TRACK_15_TC_17

Contact_No: 1
[1] 1 2 3
-------------------------------------------------------------------------------- 
Contact_No: 2
[1] 5 6
-------------------------------------------------------------------------------- 
Contact_No: 3
[1] 9 10

到目前为止,还不错,但是我希望这段代码能够包含某种1帧的间隙公差。这样最终列表看起来像这样:

Contact_No: 1
[1] 1 2 3 5 6 
-------------------------------------------------------------------------------- 
Contact_No: 2
[1] 9 10

Contact_No 1和以前的Contact_No 2已合并在一起,因为在Contact_No 1的最后一个值和以前的Contact_No 2的第一个值之间只有一个大小为1的间隙。我尝试了以下方法:

for (k in 1:length(temp2)) {
  if (k+1>length(temp2)) {
    next
  }
  if ((temp2[[k]][length(temp2[[k]])])-(temp2[[k+1]][1])<=1 & (k+1) < length(temp2)) {
    ListTemp <- c(temp2[[k]][length(temp2[[k]])], temp2[[k+1]])
    print(ListTemp)
  }
}

但是,这似乎不起作用。如果有人可以帮助我,我将非常感激! (我也乐于接受完全不同的方法)

2 个答案:

答案 0 :(得分:4)

一种方法是使用41859,找到只有1个rle,将其替换为一个,使用-1获得新值,然后根据差异不为1进行分割(即连续值),即

rep

答案 1 :(得分:3)

在您的情况下,间隙值为2。您可以通过替换第二行代码中的值来更改间隙。

ind <- which(df$TC_17 == 1)
split(ind, cumsum(c(TRUE, diff(ind) > 2)))

# $`1`
# [1] 1 2 3 5 6
# 
# $`2`
# [1]  9 10