Самая последняя дата по id, data.table R - PullRequest
1 голос
/ 28 сентября 2019

Мне нужно получить для id самую последнюю дату, для которой переменная reason равна y.

Вот пример данных:

    id group      start        end reason       prom
 1:  1     a 2009-01-01 2009-12-31      x 2016-08-15
 2:  1     a 2010-01-01 2010-12-31      x 2016-08-15
 3:  1     b 2010-01-01 2010-12-31      x 2016-08-15
 4:  1     b 2011-01-01 2011-12-31      x 2016-08-15
 5:  1     b 2012-01-01 2012-12-31      x 2016-08-15
 6:  1     a 2012-01-01 2012-12-31      x 2016-08-15
 7:  1     a 2013-01-01 2013-02-14      x 2016-08-15
 8:  1     a 2013-02-15 2013-05-31      x 2016-08-15
 9:  1     a 2013-06-01 2013-12-31      y 2016-08-15
10:  1     a 2014-01-01 2014-12-31      x 2016-08-15
11:  1     a 2015-01-01 2015-12-31      x 2016-08-15
12:  1     a 2016-01-01 2016-08-14      x 2016-08-15
13:  1     a 2016-08-15 2016-12-31      y 2016-08-15
14:  1     a 2017-01-01 2017-12-31      x 2016-08-15
15:  1     a 2018-01-01 2018-12-31      x 2016-08-15
16:  1     a 2019-01-01 9999-12-31      x 2016-08-15
17:  2     a 2009-01-01 2009-12-31      x 2016-08-15
18:  2     a 2010-01-01 2010-12-31      x 2016-08-15
19:  2     a 2011-01-01 2011-01-14      x 2016-08-15
20:  2     a 2011-01-15 2011-12-31      y 2016-08-15
21:  2     a 2012-01-01 2012-12-31      x 2016-08-15
22:  2     a 2013-01-01 2013-07-14      x 2016-08-15
23:  2     a 2013-07-15 2013-12-31      y 2016-08-15
24:  2     a 2014-01-01 2014-12-31      x 2016-08-15
25:  2     a 2015-01-01 2015-12-31      x 2016-08-15

Я попробовал:

setDT(b)[, prom := last(as.Date(b$start[b$reason == "y"]), order_by = b$start[b$reason == "y"]), by =.id)]

и

setDT(b)[, prom := max(as.Date(b$start[b$reason == "y"])), by =.(id)]

Как вы могли видеть, я не могу получить результат по ID.prom должно быть 2016-08-15, когда id равно 1, и 2013-07-15, когда id равно 2.

Любые советы о том, что я делаю неправильно, приветствуются.

Ответы [ 3 ]

2 голосов
/ 28 сентября 2019

Должно работать следующее: (1) преобразовать start в столбец Date и (2) определить prom как последнюю дату в start с reason == "y", сгруппированным по id.

library(data.table)

setDT(b)[, start := as.Date(start)][, prom := last(start[reason == "y"]), by = "id"][]
#> Registered S3 method overwritten by 'xts':
#>   method     from
#>   as.zoo.xts zoo
#>     id group      start        end reason       prom
#>  1:  1     a 2009-01-01 2009-12-31      x 2016-08-15
#>  2:  1     a 2010-01-01 2010-12-31      x 2016-08-15
#>  3:  1     b 2010-01-01 2010-12-31      x 2016-08-15
#>  4:  1     b 2011-01-01 2011-12-31      x 2016-08-15
#>  5:  1     b 2012-01-01 2012-12-31      x 2016-08-15
#>  6:  1     a 2012-01-01 2012-12-31      x 2016-08-15
#>  7:  1     a 2013-01-01 2013-02-14      x 2016-08-15
#>  8:  1     a 2013-02-15 2013-05-31      x 2016-08-15
#>  9:  1     a 2013-06-01 2013-12-31      y 2016-08-15
#> 10:  1     a 2014-01-01 2014-12-31      x 2016-08-15
#> 11:  1     a 2015-01-01 2015-12-31      x 2016-08-15
#> 12:  1     a 2016-01-01 2016-08-14      x 2016-08-15
#> 13:  1     a 2016-08-15 2016-12-31      y 2016-08-15
#> 14:  1     a 2017-01-01 2017-12-31      x 2016-08-15
#> 15:  1     a 2018-01-01 2018-12-31      x 2016-08-15
#> 16:  1     a 2019-01-01 9999-12-31      x 2016-08-15
#> 17:  2     a 2009-01-01 2009-12-31      x 2013-07-15
#> 18:  2     a 2010-01-01 2010-12-31      x 2013-07-15
#> 19:  2     a 2011-01-01 2011-01-14      x 2013-07-15
#> 20:  2     a 2011-01-15 2011-12-31      y 2013-07-15
#> 21:  2     a 2012-01-01 2012-12-31      x 2013-07-15
#> 22:  2     a 2013-01-01 2013-07-14      x 2013-07-15
#> 23:  2     a 2013-07-15 2013-12-31      y 2013-07-15
#> 24:  2     a 2014-01-01 2014-12-31      x 2013-07-15
#> 25:  2     a 2015-01-01 2015-12-31      x 2013-07-15
#>     id group      start        end reason       prom

Примечание: если даты в столбце start еще не упорядочены (как в примере набора данных), мы можем использовать вместо:

setDT(b)[, start := as.Date(start)][order(start), prom := last(start[reason == "y"]), by = "id"]

Данные

b <- structure(list(id = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), 
    group = c("a", "a", "b", "b", "b", "a", "a", "a", "a", "a", 
    "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", 
    "a", "a", "a"), start = c("2009-01-01", "2010-01-01", "2010-01-01", 
    "2011-01-01", "2012-01-01", "2012-01-01", "2013-01-01", "2013-02-15", 
    "2013-06-01", "2014-01-01", "2015-01-01", "2016-01-01", "2016-08-15", 
    "2017-01-01", "2018-01-01", "2019-01-01", "2009-01-01", "2010-01-01", 
    "2011-01-01", "2011-01-15", "2012-01-01", "2013-01-01", "2013-07-15", 
    "2014-01-01", "2015-01-01"), end = c("2009-12-31", "2010-12-31", 
    "2010-12-31", "2011-12-31", "2012-12-31", "2012-12-31", "2013-02-14", 
    "2013-05-31", "2013-12-31", "2014-12-31", "2015-12-31", "2016-08-14", 
    "2016-12-31", "2017-12-31", "2018-12-31", "9999-12-31", "2009-12-31", 
    "2010-12-31", "2011-01-14", "2011-12-31", "2012-12-31", "2013-07-14", 
    "2013-12-31", "2014-12-31", "2015-12-31"), reason = c("x", 
    "x", "x", "x", "x", "x", "x", "x", "y", "x", "x", "x", "y", 
    "x", "x", "x", "x", "x", "x", "y", "x", "x", "y", "x", "x"
    )), row.names = c(NA, -25L), class = "data.frame")
1 голос
/ 28 сентября 2019

Для каждого id мы можем получить соответствующие start даты, где reason = y и принять max значение

library(data.table)
df[, (max = max(start[reason == 'y'])), by = id]

#   id         V1
#1:  1 2016-08-15
#2:  2 2013-07-15

Если вы хотите добавить новый столбец в текущий фрейм данных,

df[, max := max(start[reason == 'y']), by = id]

Используя dplyr, мы можем сделать то же самое с помощью

library(dplyr)
df %>%
  group_by(id) %>%
  mutate(max_date = max(start[reason == 'y']))

Убедитесь, что столбец start относится к классу «Дата».

0 голосов
/ 28 сентября 2019

Я привык делать это в два этапа:

dt[reason == "y", max.date := max(start), by = id]
dt[, max.date := max(max.date, na.rm = TRUE), by = id]

Это потому, что я не знал, что вы можете фильтровать столбец по другому столбцу, как @Ronak.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...