删除行,如果它们在R中的组值的某个时间内出现



我的数据df如下所示:

Row    Timestamp            ID
1    0020-06-29 12:14:00     B 
2    0020-06-29 12:27:00     A 
3    0020-06-29 12:27:22     B  
4    0020-06-29 12:28:30     A 
5    0020-06-29 12:43:00     B 
6    0020-06-29 12:44:00     C 
7    0020-06-29 12:45:00     B 
8    0020-06-29 12:55:00     A 
9    0020-06-29 12:57:00     C 
10   0020-06-29 13:04:00     B 



Timestamp表示读取的日期和时间,ID表示标签识别码。

我要做的是用上一个时间戳5分钟内发生的相同ID删除任何Timestamp。因此,尽管在Row2和Row4中可以看到IDA,但由于数据帧的两行发生在5分钟内,我们将删除Row4,但保留Row2和Row8,这对于ID A来说发生在18分钟后。

更新:第一个时间戳应该是先决条件,从那时起,所有后续的时间戳都应该保留或删除。因此,如果我们有3个时间戳对应于同一个ID,并且时间戳1和2以及时间戳2和3之间的时间间隔分别为4.5分钟和2分钟,我希望删除时间戳2并保留1和3。这样,我们保留的下一个时间戳将是在时间戳3之后至少5分钟出现的时间戳,依此类推

我尝试过以下几种:

first_date <- df$Timestamp[1:(length(df$Timestamp)-1)]
second_date <- df$Timestamp[2:length(df$Timestamp)]
second_gap <- difftime(second_date, first_date, units="mins")
dup_index <- second_gap>5 # set this as a 5-minute threshold
dup_index <- c(TRUE, dup_index)
df_cleaned <- df[dup_index, ]

但这会删除彼此之间5分钟内的所有观测结果,并且不考虑ID。我通常只使用subset,但我使用的是大约180个独特的ID

假设我上面的评论没有发生,一个可能的解决方案如下:

library(tidyverse)
library(lubridate)
elapsed <- function(x)
{
y <- abs(as.duration(x[2:length(x)] %--% x[1:(length(x)-1)]))
y >= 5*60
} 
df %>% 
group_split(ID) %>% 
map_dfr(~ .[c(T, if (nrow(.) > 1) elapsed(.$Timestamp)),]) %>% 
arrange(Row)

输出:

# A tibble: 8 × 3
Row Timestamp           ID   
<int> <chr>               <chr>
1     1 0020-06-29 12:14:00 B    
2     2 0020-06-29 12:27:00 A    
3     3 0020-06-29 12:27:22 B    
4     5 0020-06-29 12:43:00 B    
5     6 0020-06-29 12:44:00 C    
6     8 0020-06-29 12:55:00 A    
7     9 0020-06-29 12:57:00 C    
8    10 0020-06-29 13:04:00 B    

最新更新