0

我从这篇文章中获取了一个函数来创建一个随机时间,有效地生成两个日期之间的时间和日期的随机样本

这是我的数据集:

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”和“start”时的时差。

问题:1)以上数据的结构是否符合tidy data?因为我认为传播数据更有意义,因此可以明智地采用 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"
4

1 回答 1

1

我们可以保持结构不变,但通过使用简化代码summarise(假设每个ID.

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's 没有“Start”或“O”,我们可以返回NA它们

data %>%
  group_by(ID) %>%
  summarise(diff = if (any(place == "O") & any(place == "Start"))
                   difftime(time[place == "O"], time[place == "Start"]) else NA)
于 2018-11-28T14:36:32.463 回答