【问题标题】:Adding one day at each value change在每次值更改时增加一天
【发布时间】:2018-06-07 08:35:30
【问题描述】:

我有一个包含数百万行的 data.table,格式如下。

每个ID 都有多年结果,但我只知道一年中的哪一天从 1 到 365 或 366。我不知道月份或年份,但我知道日期第一行(例如 1995/1/1)。

ID    DAY   ATRR1   ATRR2
 1      1     0.2     0.4
 2      1     1.2     0.5
 3      1     0.8     1.4
 1      2     1.3     1.5
 2      2     2.3     0.3
 3      2     1.7     1.3
 1      3     1.5     1.4
 2      3     2.1     1.3
 3      3     1.2     0.3
  ...
 1    365     1.5     1.4
 2    365     2.1     1.3
 3    365     1.2     0.3
 1      1     1.5     1.4
 2      1     2.1     1.3
 3      1     1.2     0.3
 1      2     1.3     1.5
 2      2     2.3     0.3
 3      2     1.7     1.3
  ...

我想添加一个 DATE 列,在 DAY 列中的每次更改时添加一天,因此结果将是:

ID    DAY   ATRR1   ATRR2        DATE
 1      1     0.2     0.4    1995/1/1
 2      1     1.2     0.5    1995/1/1
 3      1     0.8     1.4    1995/1/1
 1      2     1.3     1.5    1995/1/2
 2      2     2.3     0.3    1995/1/2
 3      2     1.7     1.3    1995/1/2
 1      3     1.5     1.4    1995/1/3
 2      3     2.1     1.3    1995/1/3
 3      3     1.2     0.3    1995/1/3
  ...
 1    365     1.5     1.4  1995/12/31
 2    365     2.1     1.3  1995/12/31
 3    365     1.2     0.3  1995/12/31
 1      1     1.5     1.4    1996/1/1
 2      1     2.1     1.3    1996/1/1
 3      1     1.2     0.3    1996/1/1
 1      2     1.3     1.5    1996/1/2
 2      2     2.3     0.3    1996/1/2
 3      2     1.7     1.3    1996/1/2
  ...

这怎么可能?

【问题讨论】:

  • Marc,你能发布 dput(your.data.table) 吗?
  • 您的DAY 变量中是否存在空白,或者是否对所有年份的每一天都有观察?
  • 嗨,不,根本没有间隙。一年中的每一天都有观测数据。
  • Henk:表格太大,无法发布 dput() 结果..
  • dput(head(dt, 25))

标签: r datatable


【解决方案1】:

你可以这样做:

as.Date(x, origin="1994-12-31")

我在这里的假设是,您的日期并没有按照问题中的描述进行安排,否则会产生不良结果。

样本数据:

df <- data.frame(Day = rep(c(1:365,1:2),each=3))

使用rle(运行长度编码)像这样创建seq

df$seq <- data.table::rleid(df$Day)
df$date <- as.Date(df$seq, origin="1994-12-31") #final answer
tail(df,8)

如果这是您的期望,请告诉我

样本输出:

   > tail(df,8)
     Day seq       date
1094 365 365 1995-12-31
1095 365 365 1995-12-31
1096   1 366 1996-01-01
1097   1 366 1996-01-01
1098   1 366 1996-01-01
1099   2 367 1996-01-02
1100   2 367 1996-01-02
1101   2 367 1996-01-02

【讨论】:

    【解决方案2】:

    此解决方案没有问题:

    library(data.table)
    library(lubridate)
    library(magrittr)
    
    read.table(text = "
    ID    DAY   ATRR1   ATRR2
    1      1     0.2     0.4
    2      1     1.2     0.5
    3      1     0.8     1.4
    1      2     1.3     1.5
    2      2     2.3     0.3
    3      2     1.7     1.3
    1      3     1.5     1.4
    2      3     2.1     1.3
    3      3     1.2     0.3
    1    365     1.5     1.4
    2    365     2.1     1.3
    3    365     1.2     0.3
    1      1     1.5     1.4
    2      1     2.1     1.3
    3      1     1.2     0.3
    1      2     1.3     1.5
    2      2     2.3     0.3
    3      2     1.7     1.3", header = T) %>% setDT -> x
    
    x[, date := as.Date(DAY, origin = "1995-01-01") -1]
    x[, date := {
      t1 = c(0, diff(DAY))
      t2 = ifelse(t1 < 0, 1, 0)
      t3 = cumsum(t2)
      t4 = date + years(t3)
      }]
    

    【讨论】:

    • 感谢您的解决方案。我得到了一个错误...日期+年错误(t3):算术运算符未定义“函数”和“周期”类:将一个转换为数字或匹配的时间跨度类。
    • 我已经添加了我在您的原始数据中读取的部分。这对我有用。尝试新的 R 会话。如果这不起作用,请发布 str(x) 和 sessionInfo()。
    猜你喜欢
    • 1970-01-01
    • 2017-07-28
    • 2017-11-06
    • 2022-06-09
    • 1970-01-01
    • 1970-01-01
    • 2019-10-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多