11.5 日期和时间的算术运算

R支持三个日期与时间基类的算术运算。将数字与POSIX日期相加,会以秒为单位增加时间。将数字与Date相加会以天数为单位:

  1. now_ct + 86400   # 明天。我在想世界会变成怎么样!
  2. ## [1] "2013-07-18 22:47:01 BST"
  3. now_lt + 86400   # 与 POSIXlt的行为一样
  4. ## [1] "2013-07-18 22:47:01 BST"
  5. now_date + 1    # 日期的算术运算以天为单位
  6. ## [1] "2013-07-18"

把两个日期加起来其实没有多大意义,而且会抛出一个错误。但减法操作是支持的,这会计算两个日期之间的差值。这种行为对于所有三种日期的类型都一样。请注意,在下例中,如果你不指定格式的话,as.Date会自动解析%Y-%m-%d%Y/%m/%d形式的日期:

  1. the_start_of_time <- # 按POSIX
  2. as.Date("1970-01-01")
  3. the_end_of_time <-  # 按玛雅人的阴谋论
  4. as.Date("2012-12-21")
  5. (all_time <- the_end_of_time - the_start_of_time)
  6. ## Time difference of 15695 days

使用我们已熟稔的(希望如此)classunclass的组合来查看时间存储之间的差别:

  1. class(all_time)
  2. ## [1] "difftime"
  3. unclass(all_time)
  4. ## [1] 15695
  5. ## attr(,"units")
  6. ## [1] "days"

使用difftime函数来计算出日期和时间之间的差值,它以数字的形式存储并以天为单位。由于时间之间的差别,天数被自动选择为“最敏感的”单位。差别短于一天的时间以小时、分钟或秒来表示。你可以使用difftime函数来更好地控制它的单位:

  1. difftime(the_end_of_time, the_start_of_time, units = "secs")
  2. ## Time difference of 1.356e+09 secs
  3. difftime(the_end_of_time, the_start_of_time, units = "weeks")
  4. ## Time difference of 2242 weeks

生成序列的seq函数也适用于日期。这在创建人工生成的日期(artificial date)的测试数据集时尤其有用。在by参数中,单位的选择对于POSIXdate类型是有所不同的。参考?seq.POSIXt?seq.Date帮助页面以了解每种状况下应做何选择:

  1. seq(the_start_of_time, the_end_of_time, by = "1 year")
  2. ## [1] "1970-01-01" "1971-01-01" "1972-01-01" "1973-01-01" "1974-01-01"
  3. ## [6] "1975-01-01" "1976-01-01" "1977-01-01" "1978-01-01" "1979-01-01"
  4. ## [11] "1980-01-01" "1981-01-01" "1982-01-01" "1983-01-01" "1984-01-01"
  5. ## [16] "1985-01-01" "1986-01-01" "1987-01-01" "1988-01-01" "1989-01-01"
  6. ## [21] "1990-01-01" "1991-01-01" "1992-01-01" "1993-01-01" "1994-01-01"
  7. ## [26] "1995-01-01" "1996-01-01" "1997-01-01" "1998-01-01" "1999-01-01"
  8. ## [31] "2000-01-01" "2001-01-01" "2002-01-01" "2003-01-01" "2004-01-01"
  9. ## [36] "2005-01-01" "2006-01-01" "2007-01-01" "2008-01-01" "2009-01-01"
  10. ## [41] "2010-01-01" "2011-01-01" "2012-01-01"
  11. seq(the_start_of_time, the_end_of_time, by = "500 days") # 夏天
  12. ## [1] "1970-01-01" "1971-05-16" "1972-09-27" "1974-02-09" "1975-06-24"
  13. ## [6] "1976-11-05" "1978-03-20" "1979-08-02" "1980-12-14" "1982-04-28"
  14. ## [11] "1983-09-10" "1985-01-22" "1986-06-06" "1987-10-19" "1989-03-02"
  15. ## [16] "1990-07-15" "1991-11-27" "1993-04-10" "1994-08-23" "1996-01-05"
  16. ## [21] "1997-05-19" "1998-10-01" "2000-02-13" "2001-06-27" "2002-11-09"
  17. ## [26] "2004-03-23" "2005-08-05" "2006-12-18" "2008-05-01" "2009-09-13"
  18. ## [31] "2011-01-26" "2012-06-09"

许多其他基本的函数也允许操作日期。对它们可以使用repeatround以及cut函数。也可以使用meansummary来计算均值和汇总统计值。使用methods(class = "POSIXt")以及methods(class = "Date")能查看很多相关的函数,尽管其中一些函数在处理日期时,没有特定的日期方法。