Tôi có một tập hợp các vị trí động vật với các khoảng lấy mẫu khác nhau. Những gì tôi muốn làm là nhóm và seqences nơi khoảng thời gian lấy mẫu phù hợp với một tiêu chí nhất định (ví dụ dưới một giá trị nhất định). Hãy để tôi minh họa với một số dữ liệu giả:Phân nhóm các hàng trên cơ sở sự khác biệt hàng trong R
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
Trong dữ liệu giả này, hàng 1: 3 thuộc về một nhóm, vì sự chênh lệch thời gian giữa chúng là < = 5 giây. 4 - 6 thuộc nhóm thứ hai, nhưng giả thuyết có thể có một số hàng ở giữa hai nhóm không thuộc về bất kỳ nhóm nào (TimeDiffSmall
tương đương với FALSE
).
Kết hợp thông tin từ hai câu trả lời SO nhiều (ví dụ: part 1), tôi đã tạo một hàm để giải quyết vấn đề này.
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
Chức năng này thực sự hoạt động để giải quyết vấn đề của tôi. Đây là, nó có vẻ như một cách điên rồ và tân binh để đi về điều này. Có chức năng nào có thể giải quyết vấn đề của tôi chuyên nghiệp hơn không?
Có 'cumsum (c (TRUE, diff (df $ TimeDate)> 5))' làm điều đó cho ví dụ lớn hơn của bạn? – thelatemail