使用以下代码,我将日期分为年,将这几年分为几周:
library(lubridate)
start = as.Date('2002-01-01')
end = as.Date('2017-01-01')
dates = sample(seq(as.Date('2002-01-01 00:00:00'), as.Date('2017-04-01 00:00:00'), by="day"), end-start,replace = FALSE)
splitByYears = split(dates, year(dates))
splitYearsByWeeks = lapply(splitByYears, function(x) split(x, isoweek(x)))
基于此输出,我做了几次计算。只有当我正在绘制一些数据时,我才注意到这个程序不能完美地运作:
>splitYearsByWeeks
...
$`2011`$`52`
[1] "2011-01-01" "2011-01-02" "2011-12-26"
$`2012`
$`2012`$`1`
[1] "2012-12-31" "2012-01-02" "2012-01-06" "2012-01-08"
...
这里2011-01-01和2011-01-02是2010年第52周的一部分,但由于首先逐年拆分,日期分配到2011年的第52周。同样的问题出现在2012-12-31 ,这个日期是2013年第1周的一部分,但被分配到2012年的第一周,因为我在每年分别申请该功能。
按年分割,而不是每年分成几周给我我需要的格式,但是周年关系不正确。要获得正确的周数,我可以按周划分,按年划分
splitByWeek = split(dates, isoweek(dates))
splitWeeksByYear = lapply(splitByWeek, function(x) split(x, year(x)))
但格式不是我需要的:
>splitWeeksByYear
...
$`53`
$`53`$`2004`
[1] "2004-12-31" "2004-12-29" "2004-12-28"
$`53`$`2005`
[1] "2005-01-01"
$`53`$`2009`
[1] "2009-12-28"
$`53`$`2015`
[1] "2015-12-30"
$`53`$`2016`
[1] "2016-01-03"
以我需要的格式获得正确周的最佳方式是什么:$ year $ weekNum的列表? (也许可以改变第二个结果或以其他方式完成?)
答案 0 :(得分:0)
根据ISO 8601的周编号有一个好处,即ISO周总是由7天组成,没有重叠或差距(与美国和英国的周编号惯例相反)。
然而,可能会发生新年前后的几天属于与日历日期年度不同的ISO周年的ISO周。
这就是lubridate
具有isoyear()
和isoweek()
功能以及format()
识别格式说明符%G
,%g
(ISO周)的原因基础年)和%V
(ISO周)。
因此,稍微修改一下OP的代码按预期工作:
library(lubridate)
splitByYears = split(dates, isoyear(dates))
splitYearsByWeeks = lapply(splitByYears, function(x) split(x, isoweek(x)))
splitYearsByWeeks$`2011`$`52`
[1] "2011-12-28" "2011-12-27" "2011-12-29" "2011-12-31" "2012-01-01" "2011-12-30" [7] "2011-12-26"
splitYearsByWeeks$`2012`$`1`
[1] "2012-01-03" "2012-01-07" "2012-01-06" "2012-01-04" "2012-01-08" "2012-01-05" [7] "2012-01-02"
然而,基于ISO周的年份和ISO周分割dates
也可以通过三种略微不同的方式实现:
splitted <- split(dates, format(dates, "%G-W%V"))
splitted$`2011-W52`
[1] "2011-12-28" "2011-12-27" "2011-12-29" "2011-12-31" "2012-01-01" "2011-12-30" [7] "2011-12-26"
splitted$`2012-W01`
[1] "2012-01-03" "2012-01-07" "2012-01-06" "2012-01-04" "2012-01-08" "2012-01-05" [7] "2012-01-02"
或者,您可以使用我作为作者的ISOweek
package:
splitted <- split(dates, ISOweek::ISOweek(dates))
split()
函数还接受一系列因子,在这种情况下,他们的交互用于分组:
library(lubridate)
splitted <- split(dates, list(isoyear(dates), isoweek(dates)))
splitted$`2011.52`
[1] "2011-12-28" "2011-12-27" "2011-12-29" "2011-12-31" "2012-01-01" "2011-12-30" [7] "2011-12-26"
splitted$`2012.1`
[1] "2012-01-03" "2012-01-07" "2012-01-06" "2012-01-04" "2012-01-08" "2012-01-05" [7] "2012-01-02"