difftime с запаздыванием / опережением на основе условий из другого столбца (и аккуратной структуры данных) - PullRequest
0 голосов
/ 28 ноября 2018

Я взял функцию из этого поста, чтобы создать случайное время эффективно сгенерировать случайную выборку времени и дат между двумя датами .

Вот мой набор данных:

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

Я хотел бы взять разницу во времени, когда в качестве места "O" и "начало", в каждой группе (ID).

Вопросы: 1) Соответствует ли структура приведенных выше данных приведенным данным?Потому что я думаю, что имеет больше смысла распространять данные, чтобы можно было использовать столбцы difftime.Если у каждого идентификатора есть только одна строка, это будут аккуратные данные (например, для разделения между ними можно назвать их 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 голосов
/ 28 ноября 2018

Мы можем сохранить структуру как есть, но немного упростить код, используя summarise (при условии, что у вас есть только одно «O» и «Start» для каждого 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, у которых нет ни «Старт», ни «O», мы можем вернуть NA для них

data %>%
  group_by(ID) %>%
  summarise(diff = if (any(place == "O") & any(place == "Start"))
                   difftime(time[place == "O"], time[place == "Start"]) else NA)
...