代码之家  ›  专栏  ›  技术社区  ›  thiagoveloso

r-复制数据表并创建连续日期

  •  1
  • thiagoveloso  · 技术社区  · 7 年前

    我有以下数据表:

    dt <- data.table(date=c(seq.Date(as.Date("2000-01-01"),as.Date("2000-01-03"),"1 day")),
                     a=c(1,2,3),
                     b=c(1,2,3),
                     c=c(1,2,3))
    > dt
             date a b c
    1: 2000-01-01 1 1 1
    2: 2000-01-02 2 2 2
    3: 2000-01-03 3 3 3
    

    我需要复制它 n 时间(代码取自 Repeat data.frame N times ):

    n <- 3
    dt.rep <- dt[rep(seq_len(nrow(dt)), n)]
    
    > dt.rep
             date a b c
    1: 2000-01-01 1 1 1
    2: 2000-01-02 2 2 2
    3: 2000-01-03 3 3 3
    4: 2000-01-01 1 1 1
    5: 2000-01-02 2 2 2
    6: 2000-01-03 3 3 3
    7: 2000-01-01 1 1 1
    8: 2000-01-02 2 2 2
    9: 2000-01-03 3 3 3
    

    但是,我需要 date 列是连续的。最后一行是实际的最后一个日期,我需要它返回到第一行,所以预期的输出是:

             date a b c
    1: 1999-12-26 1 1 1
    2: 1999-12-27 2 2 2
    3: 1999-12-28 3 3 3
    4: 1999-12-29 1 1 1
    5: 1999-12-30 2 2 2
    6: 1999-12-31 3 3 3
    7: 2000-01-01 1 1 1
    8: 2000-01-02 2 2 2
    9: 2000-01-03 3 3 3
    

    如何做到这一点?

    编辑:

    对于大的每小时数据集,建议的解决方案似乎失败了。考虑这个新的例子:

    dt <- data.table(date=seq(as.POSIXct("1994-01-01 00:00:00"), as.POSIXct("2008-12-31 23:00:00"), by="1 hour"), temp=runif(n=131496, min=10, max=35)) 
    > dt
                           date     temp
         1: 1994-01-01 00:00:00 26.40286
         2: 1994-01-01 01:00:00 21.37171
         3: 1994-01-01 02:00:00 16.11227
         4: 1994-01-01 03:00:00 30.28062
         5: 1994-01-01 04:00:00 25.22336
        ---                             
    131492: 2008-12-31 19:00:00 18.43148
    131493: 2008-12-31 20:00:00 24.10905
    131494: 2008-12-31 21:00:00 10.33235
    131495: 2008-12-31 22:00:00 27.73049
    131496: 2008-12-31 23:00:00 21.74835
    

    复制时 5 时代,这就是我们所拥有的:

    n <- 5
    dt[rep(seq_len(.N), n)][, newdate:=rev(seq(last(date),
                                               length.out=.N, by='-1 hour'))][]
                           date     temp             newdate
         1: 1994-01-01 00:00:00 26.40286 1933-12-31 00:00:00
         2: 1994-01-01 01:00:00 21.37171 1933-12-31 01:00:00
         3: 1994-01-01 02:00:00 16.11227 1933-12-31 02:00:00
         4: 1994-01-01 03:00:00 30.28062 1933-12-31 03:00:00
         5: 1994-01-01 04:00:00 25.22336 1933-12-31 04:00:00
        ---                                                 
    657476: 2008-12-31 19:00:00 18.43148 2008-12-31 19:00:00
    657477: 2008-12-31 20:00:00 24.10905 2008-12-31 20:00:00
    657478: 2008-12-31 21:00:00 10.33235 2008-12-31 21:00:00
    657479: 2008-12-31 22:00:00 27.73049 2008-12-31 22:00:00
    657480: 2008-12-31 23:00:00 21.74835 2008-12-31 23:00:00
    

    注意如何 日期 和 newdate 列不同步。 我希望 新日期 开始 1934-01-01 00:00:00 而是从一开始 1933-12-31 00:00:00 . 这导致数据表中有76个( length(unique(year(dt$newdate))) )多年的数据,而不是 五 复制 15 years 原来的那个= 75 年。我不知道这里发生了什么…

    1 回复  |  直到 7 年前
        1
  •  1
  •   akrun    7 年前

    后 rep 应用步骤,使用 last “日期”,得到 rev 厄尔斯 seq 通过指定 length.out 作为 .N (行数和 by 负1天

    dt[rep(seq_len(.N), n)][, date := rev(seq(last(date),
           length.out = .N, by = '-1 day'))][]
    #         date a b c
    #1: 1999-12-26 1 1 1
    #2: 1999-12-27 2 2 2
    #3: 1999-12-28 3 3 3
    #4: 1999-12-29 1 1 1
    #5: 1999-12-30 2 2 2
    #6: 1999-12-31 3 3 3
    #7: 2000-01-01 1 1 1
    #8: 2000-01-02 2 2 2
    #9: 2000-01-03 3 3 3
    

    更新

    根据运营商的意见,“日期”序列应该是 转速 每个复制的ERSED。在这种情况下,我们可以使用 代表 作为分组变量的应用程序

    n <- 5
    dt[rep(seq_len(.N), n)][, newdate := rev(seq(last(date),
       length.out = .N, by='-1 hour')), by = .(rep(seq_len(n), each = nrow(dt)))][]
    #                  date     temp             newdate
    #1: 1994-01-01 00:00:00 34.19615 1994-01-01 00:00:00
    #2: 1994-01-01 01:00:00 34.29310 1994-01-01 01:00:00
    # ...
    

    注意:使用操作日志中的更新数据