Calculate Elapsed Time Since Last Event

Calculate elapsed time since last event

Here's an approach with dplyr:

library(dplyr)
df %>%
mutate(tmpG = cumsum(c(FALSE, as.logical(diff(event))))) %>%
group_by(id) %>%
mutate(tmp_a = c(0, diff(time)) * !event,
tmp_b = c(diff(time), 0) * !event) %>%
group_by(tmpG) %>%
mutate(tae = cumsum(tmp_a),
tbe = rev(cumsum(rev(tmp_b)))) %>%
ungroup() %>%
select(-c(tmp_a, tmp_b, tmpG))

The new columns include time after event (tae) and time before event (tbe).

The result:

   id time event tae tbe
1 1 0 100 0 0
2 1 12 100 0 0
3 1 24 100 0 0
4 1 36 100 0 0
5 1 48 0 12 48
6 1 60 0 24 36
7 1 72 0 36 24
8 1 84 0 48 12
9 1 96 100 0 0
10 2 0 100 0 0
11 2 12 0 12 24
12 2 24 0 24 12
13 2 36 100 0 0
14 2 48 0 12 48
15 2 60 0 24 36
16 2 72 0 36 24
17 2 84 0 48 12
18 2 96 0 60 0
19 3 0 100 0 0
20 3 12 100 0 0
21 3 24 0 12 24
22 3 36 0 24 12
23 3 48 100 0 0
24 3 60 100 0 0
25 3 72 100 0 0
26 3 84 0 12 12
27 3 96 100 0 0

The result with the second example:

  id time event tae tbe
1 1 0 100 0 0
2 1 10 0 10 23
3 1 22 0 22 11
4 1 33 100 0 0
5 1 45 0 12 12
6 1 57 100 0 0
7 1 66 0 9 26
8 1 79 0 22 13
9 1 92 100 0 0

R - Calculate Time Elapsed Since Last Event with Multiple Event Types

The base R version of this is to use split/lapply/rbind to generate the new column.

> do.call(rbind,
lapply(
split(df, df$event_type),
function(d) {
d$dsle <- c(NA, diff(d$date)); d
}
)
)
date event_type dsle
0.1 2000-07-06 0 NA
0.7 2001-05-26 0 324
1.3 2000-10-15 1 NA
1.6 2001-04-23 1 190
2.4 2001-01-03 2 NA
2.8 2001-06-01 2 149
3.9 2001-06-30 3 NA
3.10 2001-07-02 3 2
3.12 2001-12-21 3 172
4.2 2000-09-15 4 NA
4.5 2001-03-17 4 183
4.11 2001-07-15 4 120

Note that this returns the data in a different order than provided; you can re-sort by date or save the original indices if you want to preserve that order.

Above, @akrun has posted the data.tables approach, the parallel dplyr approach would be straightforward as well:

library(dplyr)
df %>% group_by(event_type) %>% mutate(days_since_last_event=date - lag(date, 1))

Source: local data frame [12 x 3]
Groups: event_type [5]

         date event_type days_since_last_event
(date) (dbl) (dfft)
1 2000-07-06 0 NA days
2 2000-09-15 4 NA days
3 2000-10-15 1 NA days
4 2001-01-03 2 NA days
5 2001-03-17 4 183 days
6 2001-04-23 1 190 days
7 2001-05-26 0 324 days
8 2001-06-01 2 149 days
9 2001-06-30 3 NA days
10 2001-07-02 3 2 days
11 2001-07-15 4 120 days
12 2001-12-21 3 172 days

Time Elapsed Since Last Event by Group

You can do this with the dplyr package:

library(dplyr)
df %>% arrange(scoreTime) %>% group_by(matchid) %>%
mutate(sinceLast = c(NA, diff(as.POSIXlt(scoreTime), 1)))

This means:

  • arrange(scoreTime) sort it in increasing time (necessary if you're going to use diff)
  • group_by(matchid) divide into groups based on the match (what you're looking for)
  • mutate(sinceLast = c(NA, diff(as.POSIXlt(scoreTime), 1))) within each match, add a new column, called sinceLast, that describes the amount of time (in seconds) since the previous scoring event. Note that I had to add NA at the start (because for the first scoring event in a game, there is not "time since last score).

R - Calculate Time Elapsed Since Last Events with Multiple Event Types and IDs

The following uses the Chron Library to calculate difference in the dates

library(chron)

df$date <- chron(as.character(df$date),format=c(date="y-m-d"))

for(j in unique(df$id)){
DaysSince1 <-NA
DaysSince2 <-NA
RowsWithID <- grep(j,df$id)

for(i in RowsWithID){
df$days_since_event_1[i] <- df$date[i]-df$date[i-DaysSince1]
df$days_since_event_2[i] <- df$date[i]-df$date[i-DaysSince2]

if(df$event[i]==1){DaysSince1<-1}
else{DaysSince1<-DaysSince1+1}

if(df$event[i]==2){DaysSince2<-1}
else{DaysSince2<-DaysSince2+1}
}
}

This code gives the following results

> df
date event id days_since_event_1 days_since_event_2
1 00-07-06 2 1 NA NA
2 00-07-07 1 1 NA 1
3 00-07-09 0 1 2 3
4 00-07-10 0 1 3 4
5 00-07-15 2 1 8 9
6 00-07-16 1 1 9 1
7 00-07-20 0 1 4 5
8 00-07-21 1 1 5 6
9 00-07-06 1 2 NA NA
10 00-07-07 2 2 1 NA
11 00-07-15 0 2 9 8
12 00-07-16 0 2 10 9
13 00-07-17 2 2 11 10
14 00-07-18 1 2 12 1

To address you comment, you can do the following in Base R to get the number of observations rather than days. No Libraries needed.

for(j in unique(df$id)){
ObsSince1 <-NA
ObsSince2 <-NA
RowsWithID <- grep(j,df$id)

for(i in RowsWithID){
df$Obs_since_event_1[i] <- ObsSince1
df$Obs_since_event_2[i] <- ObsSince2

if(df$event[i]==1){ObsSince1<-1}
else{ObsSince1<-ObsSince1+1}

if(df$event[i]==2){ObsSince2<-1}
else{ObsSince2<-ObsSince2+1}
}
}

You should get the following output

> df
date event id Obs_since_event_1 Obs_since_event_2
1 2000-07-06 2 1 NA NA
2 2000-07-07 1 1 NA 1
3 2000-07-09 0 1 1 2
4 2000-07-10 0 1 2 3
5 2000-07-15 2 1 3 4
6 2000-07-16 1 1 4 1
7 2000-07-20 0 1 1 2
8 2000-07-21 1 1 2 3
9 2000-07-06 1 2 NA NA
10 2000-07-07 2 2 1 NA
11 2000-07-15 0 2 2 1
12 2000-07-16 0 2 3 2
13 2000-07-17 2 2 4 3
14 2000-07-18 1 2 5 1

How to calculate time elapsed since an event occurred in a specific column - Pandas DataFrames

Try with groupby:

df["date"] = pd.to_datetime(df["date"])
df["hours_since_new_sensor"] = df["date"] - df.groupby(df["type"].eq("NEW_SENSOR").cumsum())["date"].transform("min")
#reset the value before the first NEW_SENSOR to null
df["hours_since_new_sensor"] = df["hours_since_new_sensor"].where(df["type"].eq("NEW_SENSOR").cumsum()>0)

>>> df
date type hours_since_new_sensor
0 2021-11-21 00:55:00 TEXT NaT
1 2021-11-21 01:16:00 DOSE_INSULIN NaT
2 2021-11-21 02:05:00 NEW_SENSOR 0 days 00:00:00
3 2021-11-21 02:12:00 DOSE_INSULIN 0 days 00:07:00
4 2021-11-21 02:34:00 DOSE_INSULIN 0 days 00:29:00
5 2021-11-21 02:44:00 NEW_SENSOR 0 days 00:00:00

If you would like to change the time to hours, you can do:

df["hours_since_new_sensor"] = df["hours_since_new_sensor"].dt.total_seconds().div(3600)

>>> df
date type hours_since_new_sensor
0 2021-11-21 00:55:00 TEXT NaN
1 2021-11-21 01:16:00 DOSE_INSULIN NaN
2 2021-11-21 02:05:00 NEW_SENSOR 0.000000
3 2021-11-21 02:12:00 DOSE_INSULIN 0.116667
4 2021-11-21 02:34:00 DOSE_INSULIN 0.483333
5 2021-11-21 02:44:00 NEW_SENSOR 0.000000

Calculate days since last event in R

You could try something like this:

# 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

How to measure time elapsed on Javascript?

The Date documentation states that :

The JavaScript date is based on a time value that is milliseconds
since midnight January 1, 1970, UTC

Click on start button then on end button. It will show you the number of seconds between the 2 clicks.

The milliseconds diff is in variable timeDiff. Play with it to find seconds/minutes/hours/ or what you need

var startTime, endTime;
function start() { startTime = new Date();};
function end() { endTime = new Date(); var timeDiff = endTime - startTime; //in ms // strip the ms timeDiff /= 1000;
// get seconds var seconds = Math.round(timeDiff); console.log(seconds + " seconds");}
<button onclick="start()">Start</button>
<button onclick="end()">End</button>

How to calculate elapsed times for the total duration of events?

UPDATED SOLUTION

df %>% 
mutate(dur = lead(Time_Processed) - Time_Processed) %>%
replace_na(list(dur = 0)) %>%
group_by(`Modeling Code`) %>%
summarise(tot_time = sum(dur))

(^ Thanks to Nick DiQuattro)

PREVIOUS SOLUTION
Here's one solution that creates a new variable, mcode_grp, which keeps track of discrete groupings of the same Modeling Code. It's not particularly pretty - it requires looping over each row in df - but it works.

First, rename columns for ease of reference:

df <- df %>%
rename(m_code = `Modeling Code`,
d_code = `Discourse Code`)

We'll update df with a few extra variables.

- lead_time_proc gives us the Time_Processed value for the next row in df, which we'll need when computing the total amount of time for each m_code batch

- row_n for keeping track of row number in our iteration

- mcode_grp is the unique label for each m_code batch

df <- df %>%
mutate(lead_time_proc = lead(Time_Processed),
row_n = row_number(),
mcode_grp = "")

Next, we need a way to keep track of when we've hit a new batch of a given m_code value. One way is to keep a counter for each m_code, and increment it whenever a new batch is reached. Then we can label all the rows for that m_code batch as belonging to the same time window.

mcode_ct <- df %>% 
group_by(m_code) %>%
summarise(ct = 0) %>%
mutate(m_code = as.character(m_code))

This is the ugliest part. We loop over every row in df, and check to see if we've reached a new m_code. If so, we update accordingly, and register a value for mcode_grp for each row.

mc <- ""
for (i in 1:nrow(df)) {
current_mc <- df$m_code[i]
if (current_mc != mc) {
mc <- current_mc
mcode_ct <- mcode_ct %>% mutate(ct = ifelse(m_code == mc, ct + 1, ct))
current_grp <- mcode_ct %>% filter(m_code == mc) %>% select(ct) %>% pull()
}
df <- df %>% mutate(mcode_grp = ifelse(row_n == i, current_grp, mcode_grp))
}

Finally, group_by m_code and mcode_grp, compute the duration for each batch, and then sum over m_code values.

 df %>%
group_by(m_code, mcode_grp) %>%
summarise(start_time = min(Time_Processed),
end_time = max(lead_time_proc)) %>%
mutate(total_time = end_time - start_time) %>%
group_by(m_code) %>%
summarise(total_time = sum(total_time)) %>%
replace_na(list(total_time=0))

Output:

# A tibble: 4 x 2
m_code total_time
<fct> <dbl>
1 MA 12.
2 OFF 1.
3 P 0.
4 V 5.

For any dplyr/tidyverse experts out there, I'd love tips on how to accomplish more of this without resorting to loops and counters!

How to calculate the time elapsed after a button is released?

put following code in onCreate instead of btnPressed

button.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {

if (event.getAction() == MotionEvent.ACTION_DOWN) {

lastDown = System.currentTimeMillis();

} else if (event.getAction() == MotionEvent.ACTION_UP) {

lastDuration = System.currentTimeMillis() - lastDown;

//Timer starts when the button is released.
start = System.currentTimeMillis();

}
return false;
}

what happening in your code is your touchListner works only after you click your button. putting it in onCreate will make it work all the time.



Related Topics



Leave a reply



Submit