基于来自其他列(和整齐的数据结构)的条件的滞后/超前的difftime

时间:2018-11-28 14:29:49

标签: r dplyr tidyr difftime

我从这篇博文中选取了一个函数来创建随机时间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"

1 个答案:

答案 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)