【问题标题】:R - Replicate data table and create sequential datesR - 复制数据表并创建连续日期
【发布时间】:2019-02-02 18:48:38
【问题描述】:

我有如下数据表:

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

注意datenewdate 列是如何不同步的。 我希望newdate1934-01-01 00:00:00 开始,但它从1933-12-31 00:00:00 开始。这导致数据表具有 76 (length(unique(year(dt$newdate)))) 年的数据,而不是原始数据中 15 years5 复制 = 75 年。我不确定这里发生了什么......

【问题讨论】:

    标签: r date data.table


    【解决方案1】:

    replication 步骤之后,使用last“日期”,通过将length.out 指定为.N(行数和@ 987654327@ 为负 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
    

    更新

    根据 OP 的 cmets,似乎每次复制的“日期”序列应该是 reversed。在这种情况下,我们可以使用replication 作为分组变量

    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
    # ...
    

    注意:使用 OP 帖子中的更新数据

    【讨论】:

    • 我注意到代码在较大的数据集上无法正常工作。请使用此数据表尝试您的答案:dt &lt;- 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)) ,在您的答案中将-1 day 替换为-1 hour
    • @thiagoveloso 你能告诉我你注意到每小时序列的问题吗
    • 请看一下我在原帖中所做的修改。
    • @thiagoveloso 我首先用相同的数据对其进行了测试,它工作正常dt[, newdate := rev(seq(last(date), length.out=.N, by='-1 hour'))]# head(dt)# date temp newdate 1: 1994-01-01 00:00:00 17.05952 1994-01-01 00:00:00`` Now, we look at how things are working with each replication. For e.g. n1 > tail(seq(last(dt$date), length.out = n1 * 3, by = '-1 hour'), 1) [1] "1964-01-01 EST" > tail(seq(last(dt$date), length.out = n1 * 4, by = '-1 hour'), 1) [1] "1948-12-31 EST"
    • 对于复制'5',它是`> tail(seq(last(dt$date), length.out = n1 * 5, by = '-1 hour'), 1) [1 ] "1933-12-31 EST"`` 这意味着,我们正在采用从最后一个元素到第一个元素的序列,即 131496 * 5
    猜你喜欢
    • 1970-01-01
    • 2022-11-25
    • 1970-01-01
    • 2021-10-24
    • 2023-03-21
    • 2013-02-02
    • 2014-12-07
    • 2021-12-29
    • 2016-09-17
    相关资源
    最近更新 更多