[英]Split dates by year and week and get correct week number per year
使用以下代碼,我將日期分為幾年,將這幾年分為幾周 :
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年的第1周,因為我在每年分別申請功能。
按年分割而不是每年分成幾周給我我需要的格式,但是周年關系不正確。 要獲得正確的周數,我可以按周和按年拆分:
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列表? (也許可以轉換第二個結果或者以其他方式完成?)
根據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
包 :
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"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.