Ho un set di posizioni di animali con intervalli di campionamento diversi. Quello che voglio fare è raggruppare e le sequenze in cui l'intervallo di campionamento corrisponde a un determinato criterio (ad esempio è inferiore ad un certo valore). Lasciatemi illustrare con alcuni dati dummy:Raggruppamento di righe in base alle differenze di riga in 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
In questo dati fittizi, righe 1: 3 appartengono a un gruppo, in quanto la differenza di tempo tra loro è < = 5 secondi. 4 - 6 appartengono al secondo gruppo, ma ipoteticamente potrebbe esserci un numero di righe tra i due gruppi che non appartengono a nessun gruppo (TimeDiffSmall
uguale a FALSE
).
Combinando le informazioni da due risposte SO multiple (ad esempio part 1), ho creato una funzione che risolve questo problema.
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
Questa funzione funziona effettivamente per risolvere il mio problema. Questo è, sembra un modo pazzo e rookie per andare su questo. Esiste una funzione che potrebbe risolvere il mio problema in modo più professionale?
Does 'cumsum (c (TRUE, diff (df $ TimeDate)> 5))' lo fai per il tuo esempio più grande? – thelatemail