#r #dplyr
#r #dplyr
Вопрос:
У меня есть фрейм данных, структурированный следующим образом:
example <- data.frame(id = c(1,1,1,2,2,2,3,3,3),
delivereddate = c("7/20/2019","7/24/2019","7/28/2019","3/24/2019","4/13/2019","4/25/2019","11/13/2019","11/20/2019","11/27/2019"),
applieddate = c("7/22/2019","7/22/2019","7/22/2019",NA,NA,NA,"11/21/2019","11/21/2019","11/21/2019"))
Я пытаюсь добавить столбец, который идентифицирует самую последнюю дату доставки перед applieddate для каждого идентификатора. Пример того, что я пытаюсь получить для конечного результата, следующий:
desiredresult <- data.frame(id = c(1,1,1,2,2,2,3,3,3),
delivereddate = c("7/20/2019","7/24/2019","7/28/2019","3/24/2019","4/13/2019","4/25/2019","11/13/2019","11/20/2019","11/27/2019"),
applieddate = c("7/22/2019","7/22/2019","7/22/2019",NA,NA,NA,"11/21/2019","11/21/2019","11/21/2019"),
applied = c(1,0,0,0,0,0,0,1,0))
Мне нужно, чтобы применяемый столбец был двоичным (0 или 1), и для каждого идентификатора может быть только 1 строка с флагом 1. Если идентификатор не имеет applieddate, то применяемый флаг равен 0 для всех строк.
Ответ №1:
Мы могли бы использовать findInterval
library(dplyr)
library(lubridate)
example %>%
dplyr::group_by(id) %>%
dplyr::mutate(applied = (row_number() %in%
findInterval(lubridate::mdy(first(applieddate)),
lubridate::mdy(delivereddate))))
# A tibble: 9 x 4
# Groups: id [3]
# id delivereddate applieddate applied
# <dbl> <chr> <chr> <int>
#1 1 7/20/2019 7/22/2019 1
#2 1 7/24/2019 7/22/2019 0
#3 1 7/28/2019 7/22/2019 0
#4 2 3/24/2019 <NA> 0
#5 2 4/13/2019 <NA> 0
#6 2 4/25/2019 <NA> 0
#7 3 11/13/2019 11/21/2019 0
#8 3 11/20/2019 11/21/2019 1
#9 3 11/27/2019 11/21/2019 0
Ответ №2:
Вы можете преобразовать столбцы в класс date, вычесть applieddate
из delivereddate
и получить абсолютное значение. Для каждого id
мы затем присваиваем 1 индексу, где наблюдается минимальная разница.
library(dplyr)
example %>%
mutate(across(ends_with('date'), lubridate::mdy),
applied = abs(delivereddate - applieddate)) %>%
group_by(id) %>%
mutate(applied = (row_number() %in% which.min(applied)))
# id delivereddate applieddate applied
# <dbl> <date> <date> <int>
#1 1 2019-07-20 2019-07-22 1
#2 1 2019-07-24 2019-07-22 0
#3 1 2019-07-28 2019-07-22 0
#4 2 2019-03-24 NA 0
#5 2 2019-04-13 NA 0
#6 2 2019-04-25 NA 0
#7 3 2019-11-13 2019-11-21 0
#8 3 2019-11-20 2019-11-21 1
#9 3 2019-11-27 2019-11-21 0