按组查找下一个日期

时间:2016-10-28 17:35:57

标签: r data.table

我有一些这样的数据:

sample.data <- rbind(data.table(start.date=seq(from=as.Date("2010-01-01"), to=as.Date("2014-12-01"), by="quarter"),
                 Group=c("A","B","C","D"), rnorm(20, 5)),
                 data.table(start.date=seq(from=as.Date("2010-01-01"), to=as.Date("2014-12-01"), by="quarter"),
                 Group=c("A","B","C","D"), rnorm(20, 3))
                 )

我想创建一个end.date列,该列等于每个组的下一个最早start.date值。

因此,例如,start.date的第一个Group==A2010-01-01start.date的下一个最早Group==A2011-01-01。所以当按Group排序时,最终结果应如下所示:

                start.date Group   end.date
                2010-01-01     A 2011-01-01
                2010-01-01     A 2011-01-01
                2011-01-01     A 2012-01-01
                2011-01-01     A 2012-01-01
                2012-01-01     A 2013-01-01
                2012-01-01     A 2013-01-01
                2013-01-01     A 2014-01-01
                2013-01-01     A 2014-01-01
                2014-01-01     A         NA
                2014-01-01     A         NA
                2010-04-01     B 2011-04-01
                2010-04-01     B 2011-04-01
                2011-04-01     B 2012-04-01
                2011-04-01     B 2012-04-01

等等。理想情况下,我想通过引用来做到这一点,比如

sample.data[, end.date := EXPRESSION]

但我不知道从哪里开始。谢谢你的帮助。

3 个答案:

答案 0 :(得分:5)

好的:

<VirtualHost *:443>

    SSLEngine on

     ServerAdmin admin@example.com
     ServerName domain.eu
     DocumentRoot /var/www/a/public

    SSLCertificateFile /etc/apache2/ssl/apache.crt
    SSLCertificateKeyFile /etc/apache2/ssl/apache.key
    SSLCertificateChainFile  /etc/apache2/ssl/apache.crt

</VirtualHost>

在我看来,OP应该有一个类似events = unique(sample.data[ , .(Group, start.date) ]) events[, next.date := shift(start.date, type="lead"), by=Group] sample.data[events, on=c("Group", "start.date"), end.date := next.date ] 的表格,与数据库设计/ tidy data保持一致。结果看起来像

events

答案 1 :(得分:2)

初步方法

一种选择是使用dplyr工作流程:

require(dplyr); require(magrittr)
sample.data %<>%
    group_by(Group) %>% 
    mutate(end.date = sort(start.date, decreasing = FALSE)[2]) %>%

评论

您可以操纵sort功能和[n]值,以便从群组中获得第二小,最高或任何其他日期。

替代方法

在评论中进行讨论。

sample.data %<>%
    arrange(Group, start.date) %>%
    group_by(Group) %>%
    mutate(end.date2 = sort(start.date, decreasing = FALSE)[row_number(Group) + 2]) %>% 
    arrange(Group)

预览

    >> head(sample.data, n = 4)
Source: local data frame [4 x 4]
Groups: Group [1]

  start.date Group       V3  end.date2
      <date> <chr>    <dbl>     <date>
1 2010-01-01     A 4.899328 2011-01-01
2 2010-01-01     A 3.451904 2011-01-01
3 2011-01-01     A 5.779825 2012-01-01
4 2011-01-01     A 4.182594 2012-01-01

答案 2 :(得分:2)

1)Group分组,对于当前组中start.date的每个元素,在sort(unique(start.date))中查找其位置,并在下一个返回值位置:

sample.data[, end.date := {u <- sort(unique(start.date)); u[match(start.date, u) + 1]}, 
  by = Group]

2)使用ave,相同的方法也可以在没有任何包的情况下运行:

transform(sample.data, end.date = ave(start.date, Group, FUN = 
   function(x) { u <- unique(sort(x)); u[match(x, u) + 1] }))