Reputation: 2267
I have a df like this
ID <- c("A","A","A","A","A","A","A","A","B","B","B","B","B","B","B","B")
MEASUREMENT <- c("Length","Length","Length","Length","Width","Width","Width","Width","Length","Length","Length","Length","Width","Width","Width","Width")
Step <- c("1","2","3","4","1","2","3","4","1","2","3","4","1","2","3","4")
StartDatetime <- c("2015-09-29 00:00:13","2015-09-29 00:02:13","2015-09-29 00:04:13","2015-09-29 00:06:16","2015-09-29 00:07:12","2015-09-29 00:10:13","2015-09-29 00:10:23","2015-09-29 00:12:15","2015-09-29 00:14:13","2015-09-29 00:16:13","2015-09-29 00:19:14","2015-09-29 00:20:13","2015-09-29 00:24:13","2015-09-29 00:26:19","2015-09-29 00:27:20","2015-09-29 00:29:13")
EndDatetime <- c("2015-09-29 00:01:13","2015-09-29 00:03:13","2015-09-29 00:05:23","2015-09-29 00:07:11","2015-09-29 00:08:12","2015-09-29 00:10:23","2015-09-29 00:11:13","2015-09-29 00:13:13","2015-09-29 00:15:13","2015-09-29 00:17:19","2015-09-29 00:20:13","2015-09-29 00:22:13","2015-09-29 00:26:13","2015-09-29 00:27:13","2015-09-29 00:28:13","2015-09-29 00:32:13")
df1 <- data.frame(ID,MEASUREMENT,Step,StartDatetime,EndDatetime)
df1$StartDatetime <- as.POSIXct(df1$StartDatetime)
df1$EndDatetime <- as.POSIXct(df1$EndDatetime)
I am trying to calculate the elapsed time (secs) between steps grouped by ID & Measurement
If Step = 1 then the elapsed time = 0
If Step = 2 then elapsed time = StartDatetime (Step 2) - EndDatetime (Step 1)
The above logic applies for Step = 3 & 4 as well.
My desired output is
ID MEASUREMENT Step StartDatetime EndDatetime ElapsedTime
A Length 1 2015-09-29 00:00:13 2015-09-29 00:01:13 0
A Length 2 2015-09-29 00:02:13 2015-09-29 00:03:13 60
A Length 3 2015-09-29 00:04:13 2015-09-29 00:05:23 60
A Length 4 2015-09-29 00:06:16 2015-09-29 00:07:11 53
A Width 1 2015-09-29 00:07:12 2015-09-29 00:08:12 0
A Width 2 2015-09-29 00:10:13 2015-09-29 00:10:23 121
A Width 3 2015-09-29 00:10:23 2015-09-29 00:11:13 0
A Width 4 2015-09-29 00:12:15 2015-09-29 00:13:13 62
B Length 1 2015-09-29 00:14:13 2015-09-29 00:15:13 0
B Length 2 2015-09-29 00:16:13 2015-09-29 00:17:19 60
B Length 3 2015-09-29 00:19:14 2015-09-29 00:20:13 115
B Length 4 2015-09-29 00:20:13 2015-09-29 00:22:13 0
B Width 1 2015-09-29 00:24:13 2015-09-29 00:26:13 0
B Width 2 2015-09-29 00:26:19 2015-09-29 00:27:13 6
B Width 3 2015-09-29 00:27:20 2015-09-29 00:28:13 7
B Width 4 2015-09-29 00:29:13 2015-09-29 00:32:13 60
I am trying it this way but not getting it right
library(plyr)
df <- ddply(df1, .(ID,MEASUREMENT,Step),
summarize,
ElapsedTime=as.numeric(difftime(df1$StartDatetime, df1$EndDatetime,
units = "secs")))
How do I accomplish my desired output? Could someone point me in the right direction?
Upvotes: 1
Views: 81
Reputation: 2283
You can do this with some tidyverse
functions. First you group_by
the columns that you're interested in. Then with mutate
you can add another column with elapsed time calculated with a lag
(default lag of 1) which will essentially give you the value of the previous EndDatetime. Last, since the lag will default to NA, we set all NA to zero like in your example with replace_na
.
library(dplyr)
library(tidyr)
df1 %>%
group_by(ID,MEASUREMENT) %>%
mutate(ElapsedTime = StartDatetime - lag(EndDatetime)) %>%
replace_na(list(ElapsedTime =0))
# A tibble: 16 x 6
# Groups: ID, MEASUREMENT [4]
# ID MEASUREMENT Step StartDatetime EndDatetime ElapsedTime
# <fct> <fct> <fct> <dttm> <dttm> <time>
# 1 A Length 1 2015-09-29 00:00:13 2015-09-29 00:01:13 0
# 2 A Length 2 2015-09-29 00:02:13 2015-09-29 00:03:13 60
# 3 A Length 3 2015-09-29 00:04:13 2015-09-29 00:05:23 60
# 4 A Length 4 2015-09-29 00:06:16 2015-09-29 00:07:11 53
# 5 A Width 1 2015-09-29 00:07:12 2015-09-29 00:08:12 0
# 6 A Width 2 2015-09-29 00:10:13 2015-09-29 00:10:23 121
# 7 A Width 3 2015-09-29 00:10:23 2015-09-29 00:11:13 0
# 8 A Width 4 2015-09-29 00:12:15 2015-09-29 00:13:13 62
# 9 B Length 1 2015-09-29 00:14:13 2015-09-29 00:15:13 0
#10 B Length 2 2015-09-29 00:16:13 2015-09-29 00:17:19 60
#11 B Length 3 2015-09-29 00:19:14 2015-09-29 00:20:13 115
#12 B Length 4 2015-09-29 00:20:13 2015-09-29 00:22:13 0
#13 B Width 1 2015-09-29 00:24:13 2015-09-29 00:26:13 0
#14 B Width 2 2015-09-29 00:26:19 2015-09-29 00:27:13 6
#15 B Width 3 2015-09-29 00:27:20 2015-09-29 00:28:13 7
#16 B Width 4 2015-09-29 00:29:13 2015-09-29 00:32:13 60
Upvotes: 1