【问题标题】:Split dates by year and week and get correct week number per year按年和周拆分日期并获得每年正确的周数
【发布时间】:2017-09-19 10:05:02
【问题描述】:

使用以下代码,我将日期拆分为年份,今年拆分为几周

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 的列表? (也许转换第二个结果或以其他方式完成?)

【问题讨论】:

  • format(dates, "%Y-%U")?

标签: r list date data-structures lubridate


【解决方案1】:

根据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"

但是,将dates 拆分为基于 ISO 周的年份和 ISO 周也可以通过三种略有不同的方式一次性实现:

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"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多