【问题标题】:R - Turn date values into positive integersR - 将日期值转换为正整数
【发布时间】:2018-07-02 21:20:28
【问题描述】:

希望有人能指出我的具体问题的解决方案。

假设我有一个数据框,在 A 列中我有格式日期(YYYY-MM-DD,POSIXct),它们介于某个起点和终点之间(即 2017/01/01 到 2018/01/01)。在 B 列中,我有一个项目列表,在 C 列中,我有 A 中给定日期的项目数量。此外,我想添加一个假设,即尽管 A 列中的日期在已知的开始日期和结束日期之间运行,并且是有序的,它们不一定被相等的时间间隔分开。一个示例可能如下所示:

+------------+-------+----------+
|    Date    | Item  | Quantity |
+------------+-------+----------+
| 2017/01/01 | Beans |        2 |
| 2017/01/01 | Pens  |        4 |
| 2017/01/04 | Beans |        3 |
| 2017/01/04 | Pens  |        5 |
| 2017/02/01 | Tubes |        4 |
| 2017/02/03 | Beans |        9 |
+------------+-------+----------+

我想做的是添加一个列,将 A 列中的每个日期转换为一个正整数,该正整数对应于自给定开始日期以来的天数。比如开始日期是2017/01/01,我想添加以下列

+------------+-------+----------+------+
|    Date    | Item  | Quantity | Days |
+------------+-------+----------+------+
| 2017/01/01 | Beans |        2 |    1 |
| 2017/01/01 | Pens  |        4 |    1 |
| 2017/01/04 | Beans |        3 |    4 |
| 2017/01/04 | Pens  |        5 |    4 |
| 2017/01/08 | Tubes |        4 |    8 |
| 2017/01/09 | Beans |        9 |    9 |
+------------+-------+----------+------+

是否有一个简单的解决方案利用 R 的内部日期/时间处理(特别是月/闰年的天数等...)

这是评论者要求的 dput()

structure(list(date = structure(c(17167, 17167, 17170, 17170, 17174, 
17175), class = "Date"), item = structure(c(1L, 2L, 1L, 2L, 3L, 1L), 
.Label = c("Beans", "Pens", "Tubes"), class = "factor"), quantity = 
c(2, 4, 3, 5, 4, 9)), class = "data.frame", row.names = c(NA, -6L))

提前感谢您的帮助,希望我的问题可以理解。

【问题讨论】:

    标签: r datetime posixct


    【解决方案1】:
    # Example data (please make it reproducible like this in future questions):
    
    yourdata <- 
      data.frame(Quantity = c(2,4,3,5,4,9),
                 Item = c('Beans', 'Pens', 'Beans', 'Pens', 'Tubes', 'Beans'),
                 Date = c("2017/01/01", "2017/01/01","2017/01/04", "2017/01/04", '2017/01/01', "2017/01/09")
      )
    
    
    yourdata$difftime <- sapply(yourdata$Date, difftime, yourdata$Date[1]) + 1
    
      Quantity  Item       Date difftime
    1        2 Beans 2017/01/01        1
    2        4  Pens 2017/01/01        1
    3        3 Beans 2017/01/04        4
    4        5  Pens 2017/01/04        4
    5        4 Tubes 2017/01/08        8
    6        9 Beans 2017/01/09        9
    

    这也适用于您添加的 dput() 数据:

    yourdata <- structure(list(date = structure(c(17167, 17167, 17170, 17170, 17174, 
                                                  17175), class = "Date"), item = structure(c(1L, 2L, 1L, 2L, 3L, 1L), 
                                                                                            .Label = c("Beans", "Pens", "Tubes"), class = "factor"), quantity = 
                                 c(2, 4, 3, 5, 4, 9)), class = "data.frame", row.names = c(NA, -6L))
    
    yourdata$difftime <- sapply(yourdata$date, difftime, yourdata$date[1]) + 1
    
    yourdata
    
            date  item quantity difftime
    1 2017-01-01 Beans        2        1
    2 2017-01-01  Pens        4        1
    3 2017-01-04 Beans        3        4
    4 2017-01-04  Pens        5        4
    5 2017-01-08 Tubes        4        8
    6 2017-01-09 Beans        9        9
    

    【讨论】:

    • 谢谢,非常明确的回答。我已按要求添加了 dput(),但您的解决方案已经到了那里。将根据要求使其在未来可重现。再次感谢。
    • @SportScientist 乐于助人!您能否单击绿色复选标记将此标记为解决方案?
    • 没有sapply也可以做到这一点difftime(yourdata$Date, yourdata$Date[1], unit = 'day') + 1
    【解决方案2】:

    只需减去最小值并加 1。无论行顺序如何,这都将起作用。它确实假设您的数据属于 Date 类(如在您的 dput 中)。如果您的数据是POSIXct class,我建议先将其强制为Date class,否则差异将以秒为单位。调用你的数据dd

    dd$days = as.integer(dd$date - min(dd$date)) + 1
    dd
    #         date  item quantity days
    # 1 2017-01-01 Beans        2    1
    # 2 2017-01-01  Pens        4    1
    # 3 2017-01-04 Beans        3    4
    # 4 2017-01-04  Pens        5    4
    # 5 2017-01-08 Tubes        4    8
    # 6 2017-01-09 Beans        9    9
    

    【讨论】:

    • 感谢您对两个班级之间的澄清。在我使用的实际数据中,我将按照建议强制使用 Date 类。
    • 是的 - 你的问题似乎混淆了“格式”和“类”的概念,并提到了 POSIXct,它是一个日期时间类,但你的 dput 数据属于 Date 类,所以稍微具体一点似乎是值得的。 “格式”只有在它属于character 类并且尚未转换为像DatePOSIXct 这样的适当类时才真正重要。使用POSIXct 约会并没有任何优势,只有在您也有时间时才需要。
    • 谢谢,这真的很有帮助。我以前没有在 R 中处理过日期/时间,还有很多我不知道,所以你的 cmets 为我澄清了很多,希望其他任何有同样问题的人。
    【解决方案3】:
    transform(dat,dif=as.numeric(difftime(date,date[1],units = "days")+1))
    
            date  item quantity dif
    1 2017-01-01 Beans        2   1
    2 2017-01-01  Pens        4   1
    3 2017-01-04 Beans        3   4
    4 2017-01-04  Pens        5   4
    5 2017-01-08 Tubes        4   8
    6 2017-01-09 Beans        9   9
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-22
      • 2019-11-21
      • 1970-01-01
      • 2021-08-17
      • 2018-10-16
      • 2022-07-07
      相关资源
      最近更新 更多