2015-05-22 32 views
15

La mia domanda riguarda come calcolare il numero di giorni dal momento che un ultimo evento che si è verificato in R. seguito è riportato un esempio minimo dei dati:Calcolare giorni dall'ultima evento in R

df <- data.frame(date=as.Date(c("06/07/2000","15/09/2000","15/10/2000","03/01/2001","17/03/2001","23/05/2001","26/08/2001"), "%d/%m/%Y"), 
event=c(0,0,1,0,1,1,0)) 
     date event 
1 2000-07-06  0 
2 2000-09-15  0 
3 2000-10-15  1 
4 2001-01-03  0 
5 2001-03-17  1 
6 2001-05-23  1 
7 2001-08-26  0 

una variabile binaria (evento) ha valori 1 che indicano che l'evento si è verificato e 0 altrimenti. osservazioni ripetute sono fatte in tempi diversi (date) Il risultato atteso è il seguente con i giorni dall'ultima evento (tae):

date  event  tae 
1 2000-07-06  0  NA 
2 2000-09-15  0  NA 
3 2000-10-15  1   0 
4 2001-01-03  0  80 
5 2001-03-17  1  153 
6 2001-05-23  1  67 
7 2001-08-26  0  95 

ho guardato in giro per le risposte ai problemi simili, ma non affrontano il mio problema specifico Ho cercato di realizzare idee da da un post simile (Calculate elapsed time since last event) e al di sotto è il più vicino che arrivato alla soluzione:

library(dplyr) 
df %>% 
    mutate(tmp_a = c(0, diff(date)) * !event, 
     tae = cumsum(tmp_a)) 

che produce l'output mostrato di seguito, che non è abbastanza l'atteso:

 date event tmp_a tae 
1 2000-07-06  0  0 0 
2 2000-09-15  0 71 71 
3 2000-10-15  1  0 71 
4 2001-01-03  0 80 151 
5 2001-03-17  1  0 151 
6 2001-05-23  1  0 151 
7 2001-08-26  0 95 246 

Qualsiasi assistenza su come mettere a punto questo o un approccio diverso sarebbe molto apprezzata.

+0

@Pascal Se facilita l'operazione, è opportuno impostare 'tae' per le prime tre voci come' 0' anziché 'NA'. – amo

+0

@Pascal 'as.Date ('2001-01-03') - as.Date ('2000-10-15') Differenza di tempo di 80 giorni'. Questo è il no. di giorni dall'evento precedente verificatosi in "2000-10-15". Ha senso? – amo

risposta

8

si potrebbe provare qualcosa di simile:

# make an index of the latest events 
last_event_index <- cumsum(df$event) + 1 

# shift it by one to the right 
last_event_index <- c(1, last_event_index[1:length(last_event_index) - 1]) 

# get the dates of the events and index the vector with the last_event_index, 
# added an NA as the first date because there was no event 
last_event_date <- c(as.Date(NA), df[which(df$event==1), "date"])[last_event_index] 

# substract the event's date with the date of the last event 
df$tae <- df$date - last_event_date 
df 

#  date event  tae 
#1 2000-07-06  0 NA days 
#2 2000-09-15  0 NA days 
#3 2000-10-15  1 NA days 
#4 2001-01-03  0 80 days 
#5 2001-03-17  1 153 days 
#6 2001-05-23  1 67 days 
#7 2001-08-26  0 95 days 
3

E 'doloroso e si perde prestazioni, ma lo si può fare con un for ciclo:

datas <- read.table(text = "date event 
2000-07-06  0 
2000-09-15  0 
2000-10-15  1 
2001-01-03  0 
2001-03-17  1 
2001-05-23  1 
2001-08-26  0", header = TRUE, stringsAsFactors = FALSE) 


datas <- transform(datas, date = as.Date(date)) 

lastEvent <- NA 
tae <- rep(NA, length(datas$event)) 
for (i in 2:length(datas$event)) { 
    if (datas$event[i-1] == 1) { 
    lastEvent <- datas$date[i-1] 
    } 
    tae[i] <- datas$date[i] - lastEvent 

    # To set the first occuring event as 0 and not NA 
    if (datas$event[i] == 1 && sum(datas$event[1:i-1] == 1) == 0) { 
    tae[i] <- 0 
    } 
} 

cbind(datas, tae) 

date event tae 
1 2000-07-06  0 NA 
2 2000-09-15  0 NA 
3 2000-10-15  1 0 
4 2001-01-03  0 80 
5 2001-03-17  1 153 
6 2001-05-23  1 67 
7 2001-08-26  0 95 
1

vecchia questione, ma mi stava sperimentando con laminazione si unisce e ha trovato questo interessante.

library(data.table) 
setDT(df) 
setkey(df, date) 

# rolling self-join to attach last event time 
df = df[event == 1, .(lastevent = date), key = date][df, roll = TRUE] 

# find difference between record and previous event == 1 record 
df[, tae := difftime(lastevent, shift(lastevent, 1L, "lag"), unit = "days")] 

# difftime for simple case between date and joint on previous event 
df[event == 0, tae:= difftime(date, lastevent, unit = "days")] 

> df 
     date lastevent event  tae 
1: 2000-07-06  <NA>  0 NA days 
2: 2000-09-15  <NA>  0 NA days 
3: 2000-10-15 2000-10-15  1 NA days 
4: 2001-01-03 2000-10-15  0 80 days 
5: 2001-03-17 2001-03-17  1 153 days 
6: 2001-05-23 2001-05-23  1 67 days 
7: 2001-08-26 2001-05-23  0 95 days 
Problemi correlati