2017-04-22 126 views
1

用下面的代码我分裂日期,年裂枣,这几年到周按年份和周,今后每年正确的周数

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年第一周的一部分,但分配到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

'格式(日期,“%Y-%U”)'? –

回答

0

根据ISO 8601的星期编号有一个好处,即ISO周总是包含7天没有重叠或缺口(而不是美国和英国周编号约定)。

但是,新年前后的几天可能属于除日历日期年以外的其他ISO周年的ISO周。

这就是为什么lubridateisoyear()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分裂dates年和ISO周可以b E也达到一气呵成三个略有不同的方式:

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"