我从这篇博文中选取了一个函数来创建随机时间efficiently generate a random sample of times and dates between two dates。
这是我的数据集:
latemail <- function(N, st="2012/01/01", et="2012/12/31") {
st <- as.POSIXct(as.Date(st))
et <- as.POSIXct(as.Date(et))
dt <- as.numeric(difftime(et,st,unit="sec"))
ev <- sort(runif(N, 0, dt))
rt <- st + ev
}
set.seed(42);
a<- print(latemail(9))
a<- sort(a)
data <- data.frame(time= a, place=c("Start", "B", "O", "A", "A", "Start", "A", "O", "A"), ID=c(rep(1, 5), rep(2,4)))
数据如下:
time place ID
1 2012-02-19 04:40:45 Start 1
2 2012-04-14 12:34:56 B 1
3 2012-07-08 13:16:49 O 1
4 2012-08-22 07:41:26 A 1
5 2012-08-27 21:15:08 A 1
6 2012-09-14 10:22:03 Start 2
7 2012-09-25 22:30:49 B 2
8 2012-10-30 03:43:16 B 2
9 2012-11-29 22:42:03 O 2
在每个组(ID)中,当地点分别为“ O”和“开始”时,我希望采用时差。
问题:
1)以上数据的结构是否与整齐的数据一致?因为我认为散布数据更有意义,所以可以按列进行difftime。如果每个ID只有一行,它将是整齐的数据(例如,在A的之间进行分隔可以将它们称为A_1,A_2(如果必须是列))。但是哪种格式是整齐的数据。
2)有比波纹管更好的方法吗?
data2 <- data %>%
filter(place %in% c("Start", "O")) %>%
group_by(ID) %>%
mutate(diff=difftime(lead(time), time, units="days")) %>%
filter(!is.na(diff))
输出:
# A tibble: 2 x 4
# Groups: ID [2]
time place ID diff
<dttm> <fct> <dbl> <time>
1 2012-02-19 04:40:45 Start 1 140.31671 days
2 2012-09-25 22:30:49 Start 2 " 65.04947 days"
答案 0 :(得分:1)
我们可以保持结构不变,但可以使用summarise
来简化代码(假设每个ID
都只有一个“ O”和“ Start”。
library(dplyr)
data %>%
group_by(ID) %>%
summarise(diff = difftime(time[place == "O"], time[place == "Start"]))
# ID diff
# <dbl> <time>
#1 1 140.31671 days
#2 2 " 65.04947 days"
如果有一些ID
都没有“开始”或“ O”,我们可以为他们返回NA
data %>%
group_by(ID) %>%
summarise(diff = if (any(place == "O") & any(place == "Start"))
difftime(time[place == "O"], time[place == "Start"]) else NA)