Как рассчитать разницу в количестве дней с предыдущей действительной строкой данных в той же группе, не используя несколько циклов? - PullRequest
1 голос
/ 09 мая 2019

Я хотел бы рассчитать разницу в количестве дней между каждым ответом с предыдущей действительной строкой под тем же лицом / именем.

Набор упрощенных данных таков:

data <- data.frame(ID = c(1, 2, 3, 4, 5, 6),
                   Name = c("Jane", rep("May", 3), "Jane", "May"),
                   `Date Received` = as.POSIXct(c("2018-04-30 00:32", "2018-05-01 18:17",
                                       "2018-06-23 17:12", "2018-07-12 10:17",
                                       "2018-08-02 19:30", "2018-08-17 15:41")))

# ID   Name   `Date Received`
   1   Jane    2018-04-30 00:32
   2   May     2018-05-01 18:17
   3   May     2018-06-23 17:12
   4   May     2018-07-12 10:17
   5   Jane    2018-08-02 19:30
   6   May     2018-08-17 15:41

И вот результат, которого я хотел бы достичь:

# ID   Name   `Date Received`     Difference    Valid
   1   Jane    2018-04-30 00:32   NA             Y
   2   May     2018-05-01 18:17   NA             Y
   3   May     2018-06-23 17:12   53             N
   4   May     2018-07-12 10:17   72             Y
   5   Jane    2018-08-02 19:30   95             Y
   6   May     2018-08-17 15:41   37             N

Первый ответ, полученный от отправителя, всегда действителен.Ответ идентифицируется как недействительный и впоследствии игнорируется, если он получен в течение 60 дней после предыдущего действительного ответа, отправленного тем же отправителем.

Расчет разницы во времени для ответов, полученных от Джейн, является прямым, так каквсего получено 2 ответа.

Расчет за май, однако, сложен.Поскольку разница для ответа № 3 составляет 53 дня (с 2018 по 01-01 до 2018-06-23), он будет помечен как недействительный.Поэтому для расчета разницы во времени для ответа № 4 его сравнивают с ответом № 2 вместо ответа № 3, поскольку ответ № 2 является предыдущими действительными данными.Поскольку разница во времени для ответа № 4 рассчитана на 72 дня (с 2018-05-01 по 2018-07-12), она также помечается как действительный ответ.Следовательно, чтобы вычислить разницу во времени для ответа № 6 (с 2018-07-12 по 2018-08-17), его сравнивают с ответом № 4, который является предыдущими действительными данными, и т. Д.

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

Это код, который у меня есть в настоящее время, который вычисляет разницу с первым ответом, полученным ототправитель (это неправильный метод), и я не знаю, как продолжить отсюда.

data %>%
  group_by(Name) %>%
  mutate(Difference = difftime(`Date Received`, head(`Date Received`, 1), units = "days"))

Может кто-нибудь, пожалуйста, посоветовать мне решение этого вопроса, пожалуйста?

Большое спасибо!

================================================================================ Отредактировано 10/05/2019

IЯ нашел решение для каждой группы / человека, использующего цикл for, используя в качестве примера May:

name <- "May"

dates <- data %>%
  filter(Name == name) %>%
  pull(Date.Received)

diff <- NA_integer_
valid <- "Y"

for (i in 2:length(dates)) {
  day <- dates[i]
  valid_dates_pos <- tail(which(valid == "Y"), 1)
  recent_valid_day <- dates[valid_dates_pos]
  diff_days <- ceiling(as.numeric(difftime(day, recent_valid_day, units = "days")))
  diff <- c(diff, diff_days)
  valid <- c(valid, ifelse(diff_days <= 60, "N", "Y"))
}

Однако я бы хотел избежать использования вложенных циклов.

Как я могуприменять это одновременно для каждогогруппа / человек более эффективно?

1 Ответ

0 голосов
/ 10 мая 2019

Это то, что вы ищете?

n_vars <- 50
id <- seq(from=1,to=n_vars)
name <- sample(c("n1","n2","n3"),size=n_vars,replace=TRUE)
dte <- sample(seq(as.Date('2018/01/01'), as.Date('2019/01/01'), by="day"), size=n_vars)

data <- data.frame(id,name,dte) %>% 
  group_by(name) %>% 
  arrange(name,dte) %>% 
  mutate(
    diff=dte-lag(dte),
    valid=ifelse(diff<60,"Y","N")
  )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...