根据R中的行差异对行进行分组

时间:2016-03-15 22:35:18

标签: r grouping

我有一组不同采样间隔的动物位置。我想要做的是分组和序列,其中采样间隔与特定标准匹配(例如,低于某个值)。让我用一些虚拟数据来说明:

start <- Sys.time()
timediff <- c(rep(5,3),20,rep(5,2))
timediff <- cumsum(timediff)

# Set up a dataframe with a couple of time values
df <- data.frame(TimeDate = start + timediff)

# Calculate the time differences between the rows
df$TimeDiff <- c(as.integer(tail(df$TimeDate,-1) - head(df$TimeDate,-1)),NA)

# Define a criteria in order to form groups
df$TimeDiffSmall <- df$TimeDiff <= 5

             TimeDate TimeDiff TimeDiffSmall
1 2016-03-15 23:11:49        5          TRUE
2 2016-03-15 23:11:54        5          TRUE
3 2016-03-15 23:11:59       20         FALSE
4 2016-03-15 23:12:19        5          TRUE
5 2016-03-15 23:12:24        5          TRUE
6 2016-03-15 23:12:29       NA            NA

在该虚拟数据中,行1:3属于一个组,因为它们之间的时间差<= 5秒。 4 - 6属于第二组,但假设两组之间可能有多行不属于任何组(TimeDiffSmall等于FALSE)。

结合来自两个多个SO答案的信息(例如part 1),我创建了一个解决此问题的函数。

number.groups <- function(input){
  # part 1: numbering successive TRUE values
  input[is.na(input)] <- F
  x.gr <- ifelse(x <- input == TRUE, cumsum(c(head(x, 1), tail(x, -1) - head(x, -1) == 1)),NA)
  # part 2: including last value into group
  items <- which(!is.na(x.gr))
  items.plus <- c(1,items+1)
  sel <- !(items.plus %in% items)
  sel.idx <- items.plus[sel]
  x.gr[sel.idx] <- x.gr[sel.idx-1]
  return(x.gr)


 # Apply the function to create groups
 df$Group <- number.groups(df$TimeDiffSmall)

             TimeDate TimeDiff TimeDiffSmall Group
1 2016-03-15 23:11:49        5          TRUE     1
2 2016-03-15 23:11:54        5          TRUE     1
3 2016-03-15 23:11:59       20         FALSE     1
4 2016-03-15 23:12:19        5          TRUE     2
5 2016-03-15 23:12:24        5          TRUE     2
6 2016-03-15 23:12:29       NA            NA     2

这个功能实际上可以解决我的问题。这就是,这似乎是一种疯狂的新手方式。是否有一种功能可以更专业地解决我的问题?

1 个答案:

答案 0 :(得分:2)

与@thelatemail一样,我使用以下内容获取组ID。这是有效的,因为cumsum()每次到达前面的时间间隔大于5秒的元素时,最终会增加组计数。

df$Group <- cumsum(c(TRUE, diff(df$TimeDate) > 5))
df$Group
# [1] 1 1 1 2 2 2